/** 
 *-------------------------------------------------------------------   
 *                        API HANLER
 *-------------------------------------------------------------------   
 **/
function apiHandler() {
	var t		= {
		dontCheckRedirect	: false		// не проверять на редирект
	};
	
	var _cache	= {
		'loaded_flag'	: {
			// --- флаги для каждого метода 
		}
	};
	
	t.API_USER_ID	= 0;
	t.API_KEY	= '';
	
	/** служебные */
	t.update_interval	= 60000;
	
	/** проверяем не ждет ли клиент ответа от сервера? */
	function _isLoadedNow(param) {
		param	= param	|| {};

		/** помечаем что загрузка с сервера закончена */
		if (typeof param.end != 'undefined' &&  param.end) {
			_cache.load_flag	= false;
			bPopupRemoveForce();
			return false;
		}

		/** проверка по умолчанию и метка начала загрузки */
		if (_cache.load_flag	== true) {
			bLoad(30000);
			return true;
		}

		_cache.load_flag	= true;
		return false;
	}

	/** вызывается только если свободен поток. (Нет никаких других вызовов ) */
	t.callOne	= function(method,params,ok,er) {
		if (_isLoadedNow({'method':method})) {
			//log('loaded now...');
			return false;
		}
		
		t.call(method,params,ok,er);
		return true;
	}
	
	/** */
	t.call		= function(method,params,ok,er) {
		ok		= ok || function() {};
		er		= er || function() {};
		
		params		= params || {};
		var th		= this;
		params.method	= method;
		params.u	= this.API_USER_ID,
		params.s	= this.API_KEY;
		params.servertype	= typeof SERVERTYPE !='undefined' ? SERVERTYPE : '';
		
		var extra	= '';
		
		/** расширение для тестинга на деве дестени */
		if (typeof API_EXTRA !== 'undefined')
			extra	= API_EXTRA;
		
		$('.upload').removeClass('hidden');
		$.post('/api/'+extra,params,function(data){
			/** помечаем что загрузка закончена */
			//_isLoadedNow({'end':true,'method':method});
			
			$('.upload').addClass('hidden');
			if (typeof data.status != 'undefined') {
				/** независимо от текущего статуса ответа, action обновляем всегда */
				if (typeof data.actions !== 'undefined' ) {
					th.actions(data.actions);
				}
				
				if (typeof data.users !== 'undefined' ) {
					th.users(data.users);
				}
				
				if (typeof data.user_social !== 'undefined' ) {
					th.userSocial(data.user_social);
				}
					
				if (typeof data.cache !== 'undefined' ) {
					PLAYER.cache.insert(data.cache);
				}
				
				if (typeof data.redirect !== 'undefined') {
					if (th.redirect(data.redirect))
						return false;
				}
				
				/** на редирект */
				if (th.checkRedirect()) {
					return false;
				}
					
				if (data.status=='ok') {
					ok(data.response);
				} else {
					er(data.response);
				}
				autosize();
				return false;
			} else {
				/** ошибка какая-то */
				lAlert(g('ajax_post_error_json_not_found'));
			}
		},'json');
	}
	
	/** обновляем параметры для работы API */
	t.updateKey	= function(conf) {
		if (typeof conf.API_KEY != 'undefined') {
			this.API_KEY		= conf.API_KEY;
			this.API_USER_ID	= conf.API_USER_ID;
			PLAYER.user_id		= conf.API_USER_ID;
			TIME_DIFF		= intval(conf.SERVER_TIME) - intval(time());
		}
	}
	
	/** если надо выполнить какие-либо действия пришедшие с сервера */
	t.actions	= function(ar_actions) {
		for(var i in ar_actions) {
			if (ar_actions[i].type == 'money') {
				PLAYER.money.set(ar_actions[i].data);
			}
			
			if (ar_actions[i].type == 'profile') {
				PLAYER.profile.set(ar_actions[i].data);
			}
			
			if (ar_actions[i].type == 'about') {
				PLAYER.profile.set(ar_actions[i].data);
			}
			
			if (ar_actions[i].type == 'house') {
				PLAYER.house.set(ar_actions[i].data);
			}
			
			if (ar_actions[i].type == 'stat') {
				PLAYER.stat.set(ar_actions[i].data);
			}
			
			if (ar_actions[i].type == 'specials') {
				PLAYER.specials.set(ar_actions[i].data);
			}
			
			if (ar_actions[i].type == 'items') {
				PLAYER.items.set(ar_actions[i].data);
			}
			
			if (ar_actions[i].type == 'timers') {
				PLAYER.timers.set(ar_actions[i].data);
			}
			
			if (ar_actions[i].type == 'gifts') {
				PLAYER.gifts.set(ar_actions[i].data);
			}
			
			if (ar_actions[i].type == 'ordens') {
				PLAYER.ordens.set(ar_actions[i].data);
			}
			
			if (ar_actions[i].type == 'medals') {
				PLAYER.medals.set(ar_actions[i].data);
			}
			
			if (ar_actions[i].type == 'work') {
				PLAYER.work.set(ar_actions[i].data);
			}
			
			if (ar_actions[i].type == 'clan') {
				PLAYER.clan.set(ar_actions[i].data);
			}
			
			if (ar_actions[i].type == 'jssettings') {
				PLAYER.jsSettings.insert(ar_actions[i].data);	// !!! INSERT -а нет SET как везде
			}
			
			if (ar_actions[i].type == 'effects') {
				PLAYER.effects.insert(ar_actions[i].data);	// !!! INSERT -а нет SET как везде
			}
			
			if (ar_actions[i].type == 'api') {
				API.updateKey(ar_actions[i].data);
			}
			
			if (ar_actions[i].type == 'social') {
				PLAYER.social.set(ar_actions[i].data);
			}
			
			if (ar_actions[i].type == 'shown') {
				PLAYER.shown.add(ar_actions[i].data);
			}
			
			if (ar_actions[i].type == 'pet') {
				PLAYER.pet.insert(ar_actions[i].data);
			}
			
			if (ar_actions[i].type == 'actions') {
				PLAYER.actions.insert(ar_actions[i].data);
			}
			
			if (ar_actions[i].type == 'swag') {
				PLAYER.swag.insert(ar_actions[i].data);
			}
			
		}
		
		
	}
	
	/** если надо принять описание пользователей */
	t.users		= function(users) {
		for(var i in users) 
			USERJS.add(users[i]);
	}
	
	/** если надо дополняем пользователей социальной информацией */
	t.userSocial	= function(users) {
		for(var i in users) 
			USERJS.addSocial(users[i]);
	}
	
	t.redirect	= function(redirect) {
		if (intval(redirect)==0)
			return false;
		
		
		if (SKIN.nowScreen() != redirect) {
			showScreen(redirect);
			return true
		} else {
			return false;
		}
		
		
	}
	
	/** постоянный редирект - проверка вызвается на любой API */
	t.checkRedirect	= function() {
		if (this.API_USER_ID == 0 || intval(PLAYER.profile.getInfo('redirect'))==0 || this.dontCheckRedirect) {
			this.dontCheckRedirect	= false;
			//log('no redirect');
			return false;
		}
		
		//log('redirect... to '+PLAYER.profile.getInfo('redirect'));
		if (SKIN.nowScreen() != PLAYER.profile.getInfo('redirect')) {
			showScreen(PLAYER.profile.getInfo('redirect'));
			return true;
		} else {
			return false;
		}
		
	}
	
	/** ставим маркер в тасчтистику */
	t.setMarker	= function(marker_id,step) {
		
		marker_id	= _fixMarkerId(marker_id);
		
		var auth	= typeof GLOBAL.auth != 'undefined' ? GLOBAL.auth : GLOBAL.data;
		var data	= {
			'vk_id'		: auth.viewer_id,
			'marker_id'	: marker_id,
			'step'		: step
		};
		
		API.call('global.setMarker',data);
		
		/** фиксим маркеры если надо */
		function _fixMarkerId(marker_id) {
			var new_id	= marker_id;
			if (marker_id == MARKER_REG && typeof GLOBAL.data.ref_code != 'undefined' && GLOBAL.data.ref_code != '') {
				new_id	= MARKER_REG_REF;
			}
				
			return new_id;
		}
	}
	
	return t;
}

/** 
 *-------------------------------------------------------------------   
 *                        GLOBAL
 *-------------------------------------------------------------------   
 **/

/** храним текущую информацию об окружении. А также Extra кеш для разных локаций */
function globalHandler() {
	var t       = {};
        var _cache         = {
        };
	
	/** перезагружаем страницу - полностью */
	t.reloadPage	= function() {
		location.href	= t.index_page;
	}
       
        t.set		= function(key,value) {
		_cache[key]	= value;
	}
	
	t.get		= function(key) {
		if (typeof _cache[key] == 'undefined')
			return false;
		else
			return _cache[key];
	}
	
	/** устанавливаем объект по которому сейчас кликнули */
	t.setObj	= function(obj,offset) {
		offset	= offset || 0;
		
		if(SERVER_OS == 'ok'){
			offset	= offset || 60;
		}
		
		$(obj).attr({'setobj':1});
		_cache['obj']	= obj;
		_cache['obj_offset']	= offset;
	}
	
	/** получаем объект по которому сейчас произошел клик */
	t.getObj	= function() {
		var bb = false;
		if (typeof _cache['obj'] != 'undefined' && $(_cache['obj']).attr('setobj')==1) {
			bb	= _cache['obj'];
			_cache['obj']	= false;
		}
		
		return bb;
	}
	
	/** */
	t.getObjOffset	= function() {
		var bb =0;
		if (typeof _cache['obj_offset'] != 'undefined') {
			bb = _cache['obj_offset'];
			_cache['obj_offset']	= 0;
		}
		
		if (SERVER_OS == 'local')
			bb = bb +20;
		
		return bb;
	}
	
	/** */
	t.isNeedScroll	= function() {
		var bb =0;
		if (typeof _cache[GLOBAL_GET_NEED_SCROLL] != 'undefined') {
			bb = _cache[GLOBAL_GET_NEED_SCROLL];
			_cache[GLOBAL_GET_NEED_SCROLL]	= 0;
		}
		
		return bb;
	}
	
	/** обработчик кормушки */
	t.feeder	= feederHandler(t);
	function feederHandler(self) {
		var t	= {
			'self'	: self
		}
		
		var _cache	= {
			'rate_conf'	: {},	// конфиг обмена
			'rate_now'	: {},	// текущие величины обмена
			'voice'		: {}
		};
		
		/** экран кормушки */
		t.show		= function() {
			var ok	= function(r) {
				var vars	= {
					'vars'	: r
				}
				
				/** конфиги обмена */
				_cache['rate_conf']	= r.rate;
				_cache['voice']		= r.voice;
				
				/** отрисовываем */
				SKIN.popupShow(SKIN.parse('global/feeder',vars));
				
				/** "двигаем ползунки на 1 " */
				GLOBAL.feeder.onSlide('money1',1);
				GLOBAL.feeder.onSlide('money2',1);
				
				/** */
				lPopupRemove();
			}
			
			API.call('feeder.getInfo',{},ok);
		}
		
		/** когда двигаем ползунок */
		t.onSlide	= function(id,value) {
			_cache['rate_now'][id]	= value;
			$('#change_'+id).find('.change0').html(digit(floor(_cache['rate_conf'][id].amount * value)));
			$('#change_'+id).find('.change1').html(value);
		}
		
		/** пробуем обменять count социальной валюты на зелень */
		t.buy		= function(count,key) {
			count		= parseInt(count);
			var voice	= _cache['voice'][key];
			
			/** обработчик платажей вкокатакте */
			var vkBuy	= vkBuyHandler(t);
			function vkBuyHandler(self) {
				var t	= {
					self	: self
				}
				
				t.start	= function(count) {
					/** вызывается когда пришел ответ от VK по части баланса голосов */
					var ok	= function(data){
						if (data < count) {
							VK.addCallback('onBalanceChanged', function(data) {GLOBAL.feeder.buy(count);});
							VK.callMethod('showPaymentBox',count-data); // вызывали метод получения скрола, он же установит топ нашему алерту
						} else {
							/** посылаем на НАШ сервер запрос на перевод голосов */
							API.call('feeder.buy',{'count':count},t.self.ok,t.self.error);
						}
					}

					/** получаем баланса контакта */
					VK.api(
						'getUserBalance',
						function(data) {
							ok(parseInt(data.response)/100);
						}
					);
				}

				return t;
			}
			
			/** обработчик платажей одноклассники */
			var okBuy	= okBuyHandler(t);
			function okBuyHandler(self) {
				var t	= {
					self	: self
				}
				
				/** */
				t.start		= function(count) {
					var param	= PLAYER.profile.getInfo('user_id') + '|real|' + count;
					var name	= voice.summ + ' ' + get_zelen(voice.summ);
					
					/** в случае успешного платежа */
					GLOBAL.set(GLOBAL_GET_FAPI_CONFIRM,function(data) {
						/** отправляем для статистики пополнения денег на сервер */
						API.call('feeder.okBuy',{'amount':count},t.self.ok,t.self.error);
					});
					
					FAPI.UI.showPayment(name,'Моргающая зелень.Контрабанда зелени - удовольствие дорогое, поэтому зелень является самой ценной валютой на острове Ботва.',param,count, null,null,'ok', 'true');
				}
				
				return t;
			}
			
			/** обработчик платажей моего мира */
			var mirBuy	= mirBuyHandler(t);
			function mirBuyHandler(self) {
				var t	= {
					self	: self
				}
				
				/** */
				t.start		= function(count) {
					var data	= {
						// Идентификатор услуги (число), выбираемый по вашему усмотрению
						// Этот идентификатор понадобится вам в момент оказания услуги для определения  
						// Для каждой конкретной услуги должен быть постоянным и не 0.
						service_id: PLAYER.profile.getInfo('user_id'),

						// Название услуги в именительном падеже (не более 40 символов).
						// Для каждой услуги нужно определить постоянное название, например:
						// "5 золотых", "бутылка вина", "Кожаная броня 2-ого уровня".
						// В окне оплаты услуги заголовок будет: "Купить: service_name".
						// Название приложения включать в название услуги не нужно.
						service_name: voice.summ + ' ' + get_zelen(voice.summ),

						// Стоимость услуги в мэйликах.  
						// Минимальное значение 1 мэйлик
						mailiki_price: count
					}
					
					mailru.events.listen(mailru.app.events.incomingPayment, function(event) {
						/** отправляем для статистики пополнения денег на сервер */
						API.call('feeder.mirBuy',{'amount':count},t.self.ok,t.self.error);
					});
					
					mailru.app.payments.showDialog(data);
				}
				
				return t;
			}
			
			/** обработчик платажей локальных */
			var localBuy	= localBuyHandler(t);
			function localBuyHandler(self) {
				var t	= {
					self	: self
				}
				
				/** */
				t.start	= function(count) {					
					API.call('feeder.buy',{'count':count},t.self.ok,t.self.error);
				}
				
				return t;
			}
			
			/**
			 * -----------------------------------------------------
			 *			MAIN
			 * -----------------------------------------------------
			 **/
			
			if (SERVER_OS == 'ok' && !DEV_SERVER ) {
				okBuy.start(count);
			} else if (SERVER_OS == 'mir' ) {
				mirBuy.start(count);
			} else if (SERVER_OS == 'vk' && !DEV_SERVER) {
				vkBuy.start(count);
			} else {
				localBuy.start(count);
			}
			
		}
		
		/** покупаем крутого */
		t.doLord	= function() {
			var ok		= function(r) {
				GLOBAL.feeder.show();
				bOk(g('location.feeder_lord_ok'));
			}
			
			API.call('feeder.doLord',{},ok,t.error);
		}
		
		/** обмениваем имеющиеся валюты */
		t.doRate	= function(type) {
			if (typeof _cache['rate_now'][type] == 'undefined' || intval(_cache['rate_now'][type]) < 1 ) 
				return false;
			
			/** все ок */
			var ok		= function(r) {
				mineSlider({'id':'#change_'+type+' .mSlider','value2':1},'set');
				bOk(g('location.feeder_rate_ok'));
			}
			
			API.call('feeder.doRate',{'type':type,'amount':_cache['rate_now'][type]},ok,t.error);
		}
		
		/** в случае успеха мессадж */
		t.ok		= function() {
			bAlert({
				'title'		: g('global.b_ok_title2'),
				'message'	: g('location.feeder_buy_ok')
			});
		}
		
		/** стандартный обработчик */
		t.error		= function(r) {
			if (r.code == ERROR_CODE_NO_MONEY) {
				noMoney();
				return false;
			}
			bAlert(g('error.feeder_'+r.code));
		}
		
		return t;
	}
	
	/** обработчик футера*/
	t.footer	= footerHandler(t);
	function footerHandler(self) {
		var t		= {
			'self'	: self
		}
		
		/** показываем обработчик вкладки с друзьями*/
		t.friends	= friendsHandler(t);
		function friendsHandler(self) {
			var t		= {
				'self'	: self,
				'path'	: {
					'main'		: '#footer_frineds_list .scrollable',
					'block_list'	: '#footer_frineds_list',
					'block_info'	: '#footer_frineds_info'
				}
			}
			/** предустановленные параметры */
			var _param	= {
				interval	: 5000,		// раз в сколько секунд прокручиваем нашу нижнюю фигню
				page		: 0,		// типа какая вкладка сейчас
				limit		: 8,		// сколько на одну вкладку 
				scroll_flag	: true
			}

			var _cache	= {
				'fdata'	: []		// здесь храним друзей из ВК
			}

			
			/** поехали */
			t.start		= function() {
				if (count(_cache.fdata)<1) {
					_load();
				} else {
					_initSlider();
				}
			}

			/** следующая порция друзей */
			t.next		= function() {
				/** 
				* проверяем надо ли еще добавлять фоны
				**/
				var now_page = _cache.api.getSize();
				if (now_page*_param.limit < count(_cache.fdata)) {
					// если надо добавить индексы
					//log('load');
					var txt	= _html(now_page*_param.limit);
					_cache.api.addItem(txt).end();
				} else {
					//log('next');
					//log(now_page,_param.limit, count(_cache.fdata));
					_cache.api.next();
				}
				_bind();
			}
			
			/** предыдущая порция друзей */
			t.prev		= function() {
				_cache.api.prev();
			}
			
			/**
			 * -----------------------------------------------------
			 *			PROTECTED
			 * -----------------------------------------------------
			 **/

			/** грузим друзей */
			function _load() {
				/** список друзей уже храниться в PLAYER.social.getInfo('friends_app') */
				var th		= this;
				var list	= PLAYER.social.getInfo('friends_app');
				
				/* если у нас пока нет друзей в игре - ничего не делаем */
				if (count(list) < 1) {
					//log('nothing frineds');
					return false; 
				}
				
				_cache.fdata = list;
				_initSlider();
			}

			/** инициализируем слайдер */
			function _initSlider() {
				$(t.path.block_list).removeClass('hidden');
				$(t.path.block_info).addClass('hidden');
				
				//_cache.fdata	= shuffle(_cache.fdata);
				var txt	= _html(0);
				$(t.path.main).find('.area').html(txt);
				$(t.path.main).scrollable({items: '.items',circular:true,'next':'next_temp','prev':'prev_temp'});
				_cache.api	= $(t.path.main).data("scrollable");
				_bind();
			}

			/** обработчик анимации при наводении */
			function _bind() {
				$(".myself_animate").unbind().mouseenter(function(){             	            		            
					$(this).stop().animate({'margin-top' : '5px','height':'95px'}, 100 );
				}).mouseleave(function(){             	            		            
					$(this).stop().animate({'margin-top' : '12px','height':'90px'}, 100 );
				});  
			}

			/** блок новой партии слайдера */
			function _html(offset) {
				offset	= offset + 0;
				var max	= offset + _param.limit;

//				if (max > count(_cache.fdata)-1)
//					max	= count(_cache.fdata)-1;

				var txt = '<div class="clear_fix fl_l items">';
				for (var b=offset;b<=max;b++) {
					if (typeof _cache.fdata[b]!='undefined') {
						if (USERJS.get(_cache.fdata[b])==false)
							continue;
						
						var user	= USERJS.get(_cache.fdata[b]);
						var socialUser	= USERJS.getSocial(_cache.fdata[b]);
						var replace	= {
							'ADATA'	: ADATA_URL,
							'RACE'	: user.race,
							'NAME'	: socialUser != false ? socialUser.name : user.name,
							'AVA'	: socialUser != false ? socialUser.photo : ADATA_URL + '/avatars/i' + user.avatar + '.jpg',
							'SEX'	: user.sex,
							'LEVEL'	: user.level,
							'USER_ID': user.user_id
						};

						/** формируем вывод */
						txt	+= '\n\
						<div class="myself myself_animate fl_l mr3" onclick="ACTIONS.showProfile(\'{USER_ID}\');">\n\
							<span class="char_name">{NAME}</span>\n\
							<div class="gamer_avatar mauto"><img src="{AVA}" alt="" /></div>\n\
							<span class="ico race{RACE}{SEX}" ></span>\n\
							<div class="level">{LEVEL}</div>\n\
						</div>\n\
						'.format(replace);
					}else {
						txt	+= '\n\
						<div class="myself myself_animate fl_l mr3" onclick="SOCIAL.friends.inviteListAndPostWall();">\n\
							<span class="char_name ml0 w100p">Пригласить</span>\n\
							<div class="square active_square square_small cross pointer mauto" title="Пригласить друга"><div class="square_icon"></div></div>\n\
						</div>';
					}
				}
				txt	+= '</div>';
				return txt;
			}
			return t;
		}
		
		return t;
	}
		
	/** награды - дополнение */
	t.honor		= honorHandler(t) 
	function honorHandler(self) {
		var t	= {
			'self'	: self
		}
		
		/** показываем popup c медалью */
		t.showMedal	= function(id,level) {
			lAlert({
				'message'	: _getHtml(),
				'title'		: tooltips['medal_'+level+'_'+id].name
			});
			
			function _getHtml() {
				var desc	= tooltips['medal_'+level+'_'+id].desc;
				var txt		= '\n\
				<div class="">\n\
					<table class="" width="100%" cellpadding="0" cellspacing="0" border="0">\n\
						<tr>\n\
							<td valign="middle" class="w70 center mr10">\n\
								<div class="medal level_{LEVEL}_1 medal_{ID}" title=""></div>\n\
							</td>\n\
							<td valign="middle">\n\
								<span>{DESC}</span>\n\
							</td>\n\
						</tr>\n\
					</table>\n\
				</div>';
				
				return txt.format({'ID':id,'LEVEL':level,'DESC':desc});
			}
		}
		
		/** показываем popup c орденом */
		t.showOrden	= function(id) {
			lAlert({
				'message'	: _getHtml(),
				'title'		: tooltips['orden_'+id].name
			});
			
			function _getHtml() {
				var desc	= tooltips['orden_'+id].desc;
				var txt		= '\n\
				<div class="">\n\
					<table class="" width="100%" cellpadding="0" cellspacing="0" border="0">\n\
						<tr>\n\
							<td valign="middle" class="w70 center mr10">\n\
								<div class="orden orden_{ID}" title=""></div>\n\
							</td>\n\
							<td valign="middle">\n\
								<span>{DESC}</span>\n\
							</td>\n\
						</tr>\n\
					</table>\n\
				</div>';
				
				return txt.format({'ID':id,'DESC':desc});
			}
		}
		return t;
	}
	
	/** альтернативные счетчики */
	t.timer		= timerHandler(t);
	function timerHandler(self){
		var t	= {
			'self'	: self
		}
		
		var _cache = {
			'schtab'	: {
				data	: {},
				interval: 0
			}
		};
		
		t.add	= function(mode,time, id){
			_cache[mode].data[id] = {
				'time'		: time,
				'id'		: id,
				'refreshed'	: false
			};
		}
		
		t.start	= function(mode){			
			clearInterval(_cache[mode].interval);
			var need_refresh = false;
			
			_cache[mode].interval = setInterval(function(){
				for (var key in _cache[mode].data){
					if(_cache[mode].data[key].time > time()){
						var _id = _cache[mode].data[key].id;
						var _time = _cache[mode].data[key].time;
//						log('id: '+_id+', time: '+_time+'');

						$('#'+_id).html(toDate(_time));

					} else if (!_cache[mode].data[key].refreshed) {
						_cache[mode].data[key].refreshed	= true;
						need_refresh				= true;
					}
				}
				
				if(need_refresh){
					clearInterval(_cache[mode].interval);
					
					ACTIONS.schtab.screenMain();
				}
				
			}, 1000);
			
		}
		
		t.clear	= function(mode) {
			clearInterval(_cache[mode].interval);
		}
		return t;
	}
		
	return t;
}

/** 
 *-------------------------------------------------------------------   
 *                        SKIN
 *-------------------------------------------------------------------   
 **/
function skinHandler() {
	var _cache	= {};
	var datastore	= {
		'actions'	: {}
	}
	
	var t		= {
		no_crumbs	: false, // Флаг для того чтобы скрывать \ покахывать область для крошек 
		now_screen	: false,
		now_popup	: 0,
		path		: {
			'main'		: '#content',
			'ajax_content'	: '#ajax_content',
			'popup'		: '#popup',
			'overlay'	: '#overlay'
		}
	};
	
	
	/** 
	 *----------------------------------------------------------- 
	 *		Вложенные объекты
	 *----------------------------------------------------------- 
	 **/
	
	t.profile	= profileHandler(t);
	function profileHandler(self) {
		var t	= {};
		t.self	= self;
		t.path	= {
			'potion_11'	: '#reload_potion_11',
			'potion_1'	: '#reload_potion_1',
			'potion_2'	: '#reload_potion_2',
			'potion_3'	: '#reload_potion_3'
		}
	
		/** обновляем кол-во зелей у игрока */
		t.reloadPotion	= function() {
			var info	= PLAYER.specials.getInfo();
			for (var i in info) {
				if (typeof this.path[i]!=='undefined')
					$(this.path[i]).html(info[i]);
			}
		}
	
		/** ВЕЩИ СПРАВА ОТ АВАТАРА УЖЕ ОДЕТЫЕ */
		t.reloadItems	= function() {
			var items = PLAYER.items.getInfo();
			for (var group = 2; group<=6;group++) {
				for (var index in items) {
					var item	= items[index];
					
					if (item.group != group)
						continue;
					
					/** ВАЖНО - ЭТО НЕ ОДЕВАЛКА, А ВЕЩИ СПРАВА ОТ АВАТАРА УЖЕ ОДЕТЫЕ */
					if (item.activated == 1 ) {
						/** ! эти данные должны согласовываться в player_main - данными в одевалке */
						var replace	= {
							'ID'		: item.id,
							'IMG'		: typeof item.img_url != 'undefined' ? item.img_url : IMG_URL + '/images/items/' + item.img + 's.jpg',
							'TOOLTIP'	: "{'type':'items','tooltip_id':'{TOOLTIP_ID}','id':'{ID}','extra':{'room':'','index':'{INDEX}','extra':{TOOLTIP_EXTRA}}}".format({'TOOLTIP_ID':item.tooltip_id,'TOOLTIP_EXTRA':item.tooltip_extra,'INDEX':index,'ID':item.item_id}),
							'INDEX'		: index
						};
						
						var txt = "<div onmouseover=\"TOOLTIP.show(this,{TOOLTIP});\" class='w60 h60' onclick=\"PLAYER.items.deActivate('{INDEX}');\" style='background: url({IMG}) no-repeat;'  id='tutorial_item_dress_{ID}'></div>".format(replace);	
						$('#reload_group_'+item.group).html(txt);
						break;
					} else {
						var txt = '<div class="square_icon iconItem60 ico_group_{GROUP}" onmouseover="TOOLTIP.hint(this,\'player_items_activated\');"></div>'.format({'GROUP':item.group});
						$('#reload_group_'+item.group).html(txt);
					}
				}
			}
		}
	
		/** когда снимаем вещь - обновляем параметры трнировки */
		t.reloadTraining	= function() {
			var txt		= '';
			var stat	= PLAYER.profile.getInfo('stats');
			
			for(var key in stat) {
				var replace	= {
					'ICO'		: g('icon.stat_'+key),
					'PERCENT'	: stat[key].percent,
					'ALL'		: stat[key].all,
					'HINT'		: 'stat_'+key,
					'ADVANCED'	: intval(stat[key].advanced) > 0  ? '+' + stat[key].advanced : stat[key].advanced
				}
				
				txt	+=	'\n\
				<div class="clear_fix pl3 pb2" onmouseover="TOOLTIP.hint(this,\'{HINT}\',{arrow_left:-79});">\n\
					<div class="fl_l mt7">{ICO}</div>\n\
					<div class="fl_r w156">\n\
						<div class="bold center mr20 h16 mb-1">{ALL}</div>	\n\
						<span class="smallest_hud">{ADVANCED}</span>\n\
						<div class="ability_hud"><div style="width: {PERCENT}%;"></div></div>\n\
					</div>\n\
				</div>'.format(replace);
				
				if (key!='charisma')
					txt	+= '<div class="border_b"></div>';
			}
			$('#reload_training_block').html(txt);
		}
	
		/** отображаем тотемы у игрока */
		t.reloadHouse		= function() {
			/** проверяем сейфы */
			var code	= '';
			if (PLAYER.house.have('safe1')) {
				code	= '10';
			}
			
			if (PLAYER.house.have('safe2')) {
				code	= '11';
			}
			
			if (PLAYER.house.have('safe3')) {
				code	= '30';
			}
			
			if (PLAYER.house.have('safe4')) {
				code	= '41';
			}
			
			if (code !='') {
				$('#reload_safe1').addClass('active'+ code);
			}
			
			/** все остальное */
			var ar	= ['totem1','totem2','woodoo1','woodoo2'];
			for(var key in ar) {
				var value	= ar[key];
				if (PLAYER.house.have(value)) {
					$('#reload_'+value).addClass('active');
				} else {
					$('#reload_'+value).removeClass('active');
				}
			}
		}
		
		/** обновляем жизнь и опыт */
		t.reloadLife		= function() {
			/** уровень */
			$('#reload_level').html(PLAYER.profile.getInfo('level'));
			
			/** жизнь */
			var txt = '\n\
				<div style="width: {LIFE}%; {BACKGROUND}"></div>\n\
				<div style="color: #fff; text-shadow: 0px 0px 3px #000;">{LIFE}%</div>\n\
				'.format({'LIFE':PLAYER.profile.getInfo('life_energy_percent'), 'BACKGROUND':PLAYER.profile.getInfo('life_energy_percent') < 31 ? 'background-position: 0 -16px;' : 'background-position: 0 -46px;'});
			$('#reload_life_energy').html(txt);
			
			/** опыт  */
			var txt = '\n\
				<div style="width: {EXP}%; background-position: 0 -61px;"></div>\n\
				<div style="color: #F7F0E2;">{EXP}%</div>\n\
				'.format({'EXP':PLAYER.profile.getInfo('exp_percent')});
			//$('#reload_exp').html(txt);
			
		}
		
		/** изображение пета в правом верхнем углу */
		t.reloadPet		= function() {
			$('#pet_status_0').addClass('hidden');
			$('#pet_status_1').addClass('hidden');
			
			$('#pet_status_'+PLAYER.pet.getInfo('status')).removeClass('hidden');
			
			/** жизнь */
			var txt = '\n\
				<div style="width: {LIFE}%; {BACKGROUND}"></div>\n\
				<div style="color: #fff; text-shadow: 0px 0px 3px #000;">{LIFE}%</div>\n\
				'.format({'LIFE':PLAYER.pet.getInfo('life_percent'), 'BACKGROUND':PLAYER.pet.getInfo('life_percent') < 31 ? 'background-position: 0 -16px;' : 'background-position: 0 -46px;'});
			$('#reload_life_energy_pet').html(txt);
			/** */
		}
		
		/** одевалка на странице игрока */
		t.reloadItemsAll	= function() {
			
			$('#path_items_all').html('');
			
			/** сколько линий в одевалке */
			var line = PLAYER.house.getInfo('house_space') > 8 ? 16 : 8;  

			var items = PLAYER.items.getInfo();
			var a = 0;

			for(var i in items) {

				var item	= items[i];

				if (item.bag == 6){
					continue;
				}

				a++;

				/** ! эти данные должны согласовываться в SKIN.profile.reload() */

				var replace	= {
					'ID'		: item.item_id,
					'CLS'		: item.activated == 1 ? '' : '',
					'IMG'		: typeof item.img_url != 'undefined' ? item.img_url : IMG_URL + '/images/items/' + item.img + 's.jpg',
					'TOOLTIP'	: "{'type':'items','tooltip_id':'{TOOLTIP_ID}','id':'{ID}','extra':{'room':'dressingroom','index':'{INDEX}','extra':{TOOLTIP_EXTRA}}}".format({'TOOLTIP_ID':item.tooltip_id,'TOOLTIP_EXTRA':item.tooltip_extra,'INDEX':i,'ID':item.item_id}),
					'CLICK'		: in_array(intval(item.group),[1,2,3,4,5]) && item.item_id == 4 ? 'onclick="PLAYER.items.activate(\''+i+'\'); TUTORIAL.click(this); TUTORIAL.onBind(JS_SETTINGS_TUTORIAL_BEGIN_STEP4, \'step20\');"' : in_array(intval(item.group),[1,2,3,4,5]) && item.item_id == 61 ? 'onclick="PLAYER.items.activate(\''+i+'\'); TUTORIAL.click(this); TUTORIAL.onBind(JS_SETTINGS_TUTORIAL_BEGIN_STEP4, \'step21\');"' : 'onclick="PLAYER.items.activate(\''+i+'\');"'
					
				};
				
				var txt = "<div onmouseover=\"TOOLTIP.show(this,{TOOLTIP});\" {CLICK} class='square active_square fl_l pointer {CLS}' style='background: url({IMG}) no-repeat;' id='tutorial_item_dress_{ID}'><div></div></div>".format(replace);

				$('#path_items_all').append(txt);
			}
			
			/** добиваем оставшиеся */
			for (var b = a+1;b<=line;b++) {
				var replace = {
					'LOCK'	: PLAYER.house.getInfo('house_space') < b ? 'blocked' : 'cross',
					'HINT'	: PLAYER.house.getInfo('house_space') < b ? 'uprade_house' : 'go_to_village_shop',	// код текста из g('hint.');
					'CLICK'	: PLAYER.house.getInfo('house_space') < b ? 'ACTIONS.village.screenHouse(1);' : 'showScreen(SCREEN_VILLAGE_SHOP);'
				};
						var txt = "<div class='square active_square fl_l pointer {LOCK}' onmouseover=\"TOOLTIP.hint(this,'{HINT}');\" onclick=\"{CLICK}\"><div class='square_icon'></div></div>".format(replace);

				$('#path_items_all').append(txt);

			}
		}
		
		/** кулоны на странице игрока */
		t.reloadCotomkaMain		= function() {
			$('#path_coulombs').html('');
			
			/** сколько линий в одевалке */
			var line = PLAYER.swag.getInfo('size');
			var items = PLAYER.items.getInfo();
			var a = 0;

			for(var i in items) {

				var item	= items[i];

				if (item.bag != 6){
					continue;
				}

				a++;

				/** ! эти данные должны согласовываться в SKIN.profile.reload() */

				var replace	= {
					'ID'		: item.item_id,
					'CLS'		: item.activated == 1 ? '' : '',
					'IMG'		: typeof item.img_url != 'undefined' ? item.img_url : IMG_URL + '/images/items/' + item.img + 's.jpg',
					'TOOLTIP'	: "{'type':'items','tooltip_id':'{TOOLTIP_ID}','id':'{ID}','extra':{'room':'dressingroom','index':'{INDEX}','extra':{TOOLTIP_EXTRA}}}".format({'TOOLTIP_ID':item.tooltip_id,'TOOLTIP_EXTRA':item.tooltip_extra,'INDEX':i,'ID':item.item_id}),
					'CLICK'		: in_array(intval(item.group),[1,2,3,4,5]) && item.item_id == 4 ? 'onclick="PLAYER.items.activate(\''+i+'\'); TUTORIAL.click(this); TUTORIAL.onBind(JS_SETTINGS_TUTORIAL_BEGIN_STEP4, \'step20\');"' : in_array(intval(item.group),[1,2,3,4,5]) && item.item_id == 61 ? 'onclick="PLAYER.items.activate(\''+i+'\'); TUTORIAL.click(this); TUTORIAL.onBind(JS_SETTINGS_TUTORIAL_BEGIN_STEP4, \'step21\');"' : 'onclick="PLAYER.items.activate(\''+i+'\');"'
					
				};
				
				var txt = "<div onmouseover=\"TOOLTIP.show(this,{TOOLTIP});\" {CLICK} class='square active_square fl_l pointer {CLS}' style='background: url({IMG}) no-repeat;' id='tutorial_item_dress_{ID}'><div></div></div>".format(replace);

				$('#path_coulombs').append(txt);
			}
			
			/** добиваем оставшиеся */
			for (var b = a+1;b<=line;b++) {
				var replace = {
					'LOCK'	: 'cross',
					'HINT'	: 'add_to_swag',	// код текста из g('hint.');
					'CLICK'	: 'showScreen(SCREEN_VILLAGE_SHOP);'
				};
						var txt = "<div class='square active_square fl_l pointer {LOCK}' onmouseover=\"TOOLTIP.hint(this,'{HINT}');\" onclick=\"{CLICK}\"><div class='square_icon'></div></div>".format(replace);

				$('#path_coulombs').append(txt);

			}
		}
		
		/** котомка с кулонами */
		t.reloadCotomkaTop		= function() {
			
			$('#path_small_coulomb').html('');
			var line = 4;
			var items = PLAYER.items.getInfo();
			var a = 0;
			
			var ar_for_screen = [];
			
			for (var i in items) {
				var param	= PLAYER.swag.isActive() ? items[i].bag : items[i].group;
				if (param == 6 && items[i].activated == 1)
					ar_for_screen.push(items[i]);
			}

			/** теперь у нас в ar_for_screen - первый эелмент активированный кулон */
			/** заносим остальные  **/
			for (var i in items) {
				var param	= PLAYER.swag.isActive() ? items[i].bag : items[i].group;
					if (param == 6 && items[i].activated != 1)
					ar_for_screen.push(items[i]);
			}

			/** выводим кулоны перебирая ar_for_screen*/
			for (var i in ar_for_screen) {
				var item = ar_for_screen[i];
				
				a++;
				
				var replace	= {
					'ID'		: item.item_id,
					'CLS'		: item.activated == 1 ? 'rating_bgr1' : '',
					'CLICK'		: PLAYER.swag.isActive() ? 'onclick="PLAYER.items.activate(\''+item.id+'\');"' : 'onclick="GLOBAL.setObj(this,300); bAlert(g(\'location.swag_need_active\'));"'
				};
				var txt = "<div class=\"w21 h21 square active_square {CLS} fl_l mr3\" {CLICK} id='tutorial_item_dress_{ID}'><b class='ml1 mt1 icon item_{ID}'></b></div>".format(replace);

				

				$('#path_small_coulomb').append(txt);
			}
			
			/** добиваем оставшиеся */
			for (var b = a+1;b<=line;b++) {
				var replace = {
					'CLICK'	: ''
				};
				var txt = "<div class=\"w21 h21 square active_square fl_l mr3\" onclick=\"{CLICK}\"></div>".format(replace);	

				$('#path_small_coulomb').append(txt);

			}
		}
		
		/** котомка с кулонами - выпадающая */
		t.reloadCotomkaDropped		= function() {
			$('#path_cotomka_dropped').html('');
			var line = 4;
			var items = PLAYER.items.getInfo();
			var a = 0;
			
			var ar_for_screen = [];
			
			for (var i in items) {
				var param	= PLAYER.swag.isActive() ? items[i].bag : items[i].group;
				if (param == 6 && items[i].activated == 1)
					ar_for_screen.push(items[i]);
			}

			/** теперь у нас в ar_for_screen - первый эелмент активированный кулон */
			/** заносим остальные  **/
			for (var i in items) {
				var param	= PLAYER.swag.isActive() ? items[i].bag : items[i].group;
					if (param == 6 && items[i].activated != 1)
					ar_for_screen.push(items[i]);
			}

			/** выводим кулоны перебирая ar_for_screen*/
			for (var i in ar_for_screen) {
				var item = ar_for_screen[i];
				
				a++;
				
				var replace	= {
					'ID'		: item.item_id,
					'CLS'		: item.activated == 1 ? 'rating_bgr1' : '',
					'CLICK'		: PLAYER.swag.isActive() ? 'onclick="PLAYER.items.activate(\''+item.id+'\');"' : 'onclick="GLOBAL.setObj(this,300); bAlert(g(\'location.swag_need_active\'));"'
				};
				var txt = "<div class=\"w21 h21 square active_square {CLS} fl_l mr3\" {CLICK} id='tutorial_item_dress_{ID}'><b class='ml1 mt1 icon item_{ID}'></b></div>".format(replace);

				$('#path_cotomka_dropped').append(txt);
			}
		}
		
		/** обноваляем все значения игрока на странице */
		t.reload	= function() {
			this.reloadPotion();
			this.reloadItems();
			this.reloadTraining();
			this.reloadHouse();
			this.reloadLife();
			this.reloadItemsAll();
			this.reloadCotomkaMain();
			this.reloadCotomkaTop();
			this.reloadCotomkaDropped();
			
			autoSize();
		}
		
		return t;
	}
	
	/** 
	 *----------------------------------------------------------- 
	 *		Методы
	 *----------------------------------------------------------- 
	 **/
	
	/** возращает текущий шаблон */
	t.parse		= function(template,vars) {
		var dop	= '';
		DEBUG.template(template);
		if (DEV_SERVER || SERVER_OS == 'local')
			dop = "?v="+time();
		else
			dop = "?v="+JS_CSS_VERSION;
		
		return new EJS({url: '/release/'+RELEASE_VERSION+'/templates/'+template+'.ejs'+dop}).render(vars);
	}
	
	/** вписываем в главный div */
	t.content	= function(txt,type) {
		type	= type || 'html';
		
		if (type === 'html') {
			$(this.path.main).html(txt);
		} else if (type === 'prepend') {
			$(this.path.main).prepend(txt);
		} else if (type === 'append') {
			$(this.path.main).append(txt);
		}
		
		autoSize();
	} //
        
	/** вписываем в #ajax_content */
	t.ajaxContent	= function(txt,type) {
		type	= type || 'html';
		
		if (type === 'html') {
			$(this.path.ajax_content).html(txt);
		} else if (type === 'prepend') {
			$(this.path.ajax_content).prepend(txt);
		} else if (type === 'append') {
			$(this.path.ajax_content).append(txt);
		}
		
		autoSize();
	} //
	
	/** вписываем в #popup */
	t.popupShow	= function(txt,on_close,now_popup) {
		//arrow('clearAll');
		this.now_popup	= now_popup || POPUP_UNDEFINED;
		
		if (typeof on_close!= 'undefined') {
			_cache[ON_CLOSE_POPUP]	= on_close;
		}
		
		var th	= this;
		$(this.path.popup).removeClass();
		$(this.path.popup).html(txt);           
		
		/** позиционируем popup */
		_popupPos(this.path.popup,{top:-20},function(){
			th.overlayShow();
			$(th.path.popup).fadeIn("fast");
			TUTORIAL.checkWait();
			SKIN.afterShow();
		});
		
		/** ставим прозрачность на стрелочки */
		$('.arrow').each(function(){
			if (!$(this).hasClass('zindexmax'))
				$(this).addClass('opacity0');
		});
		
		TOOLTIP.hide(true);
		autoSize();
	} //
	
	t.popupClose	= function() {
		this.now_popup	= POPUP_UNDEFINED;
		this.overlayHide();
		$(this.path.popup).fadeOut("fast");
		
		if (typeof _cache[ON_CLOSE_POPUP] != 'undefined' && _cache[ON_CLOSE_POPUP] != false && typeof _cache[ON_CLOSE_POPUP] == 'function') {
			_cache[ON_CLOSE_POPUP]();
			_cache[ON_CLOSE_POPUP]	= false;
		}
		autoSize();
		
		/** ставим прозрачность на стрелочки */
		$('.arrow').each(function(){
			$(this).removeClass('opacity0');
		});
		
		TUTORIAL.onClosePopup();
	}
	
	/** показываем - экран wiki - в txt - ее контент */
	t.showWiki	= function(txt) {
		alert(txt);
	}
	
	/** показываем "начальный экран" */
	t.first		= function(txt) {
		var html	= SKIN.parse('global/firstContainer',{'content':txt});
		this.content(html);
	}
	
	/** показываем "общую страницу" */
	t.main		= function(txt,screen) {
		/** скрываем popup && hint */
		arrow('clearAll');	
		if (GLOBAL.isNeedScroll())
			scroll(0);
		
		screen		= screen || SCREEN_UNDEFINED;
		this.now_screen	= screen;	// текущий экран
		
		var vars	= {
			'info'		: {
				'avatar'	: PLAYER.profile.getInfo('avatar'),
				'name'		: PLAYER.profile.getInfo('name'),
				'race'		: PLAYER.profile.getInfo('race'),
				'sex'		: PLAYER.profile.getInfo('sex'),
				'life_energy_percent' : PLAYER.profile.getInfo('life_energy_percent'),
				'exp_percent'	: PLAYER.profile.getInfo('exp_percent'),
				'level'		: PLAYER.profile.getInfo('level'),
				'count_new_post': PLAYER.profile.getInfo('count_new_post'),
				'count_new_quest': PLAYER.profile.getInfo('count_new_quest')
			},
			
			'money'		: {
				'money1'	: digit(PLAYER.money.getInfo('money1')),
				'money2'	: digit(PLAYER.money.getInfo('money2')),
				'money3'	: digit(PLAYER.money.getInfo('money3')),
				'money10'	: digit(PLAYER.money.getInfo('money10'))
			},
			
			/** таймеры */
			'timers'	: {
				'work'		: PLAYER.timers.getTimerInfo('work'),
				'protection'	: PLAYER.timers.getTimerInfo('protection'),
				'fighting'	: PLAYER.timers.getTimerInfo('fighting')
			},
			
			/** главный контент */
			'content'		: txt,
			'title'			: this.getInfo('title'),
			'crumbs'		: this.getInfo('crumbs_txt')
		}
		//log(vars);
		var html	= SKIN.parse('global/mainContainer',vars);
		this.content(html);
		PLAYER.work.checkTimers();
		TOOLTIP.hide(true);
		lPopupRemove();
		TUTORIAL.checkWait();
		SKIN.afterShow();
		if(SKIN.nowScreen() != SCREEN_SCHTAB){
			GLOBAL.timer.clear('schtab');
		}
	}
	
	/** обнвляем содержимео главного экрана, без перезагрузки */
	t.update	= function(txt) {
		if ($('#ajax_content2').hasClass('hidden')) {
			//log('update 2');
			$('#ajax_content2').html(txt).removeClass('hidden');
			$('#ajax_content').addClass('hidden').html('');
		} else {
			//log('update 1');
			$('#ajax_content').html(txt).removeClass('hidden');
			$('#ajax_content2').addClass('hidden').html('');
		}
		
		autoSize();
	}
	
	/** возращает какорй экран сейчас показ. Нужно чтобы когда завершаем работу - производить какие-то действия, Елси показан больой экра работы */
	t.nowScreen	= function() {
		return this.now_screen;
	}
	
	/** */
	t.nowPopup	= function() {
		return this.now_popup;	
	}
	
	/** возращает полный путь к аватару пользователя */
	t.getAvatarUrl	=  function(user_id,avatar,type) {
		return ADATA_URL + "/avatars/" + type.substr(0,1) + avatar + '.jpg';
	}
	
	/** */
	t.setCrumbs	= function(conf) {
		_cache['crumbs']	= [];
		for (var i in conf) {
			if (typeof conf[i]== "function") {
				var action	= 's_' + time() + '_' + mt_rand(1000,1000000);
				datastore['actions'][action]	= conf[i];
				var txt		= '<span onclick="SKIN.crumbsClick(\''+action+'\');">'+i+'</span>';
				_cache['crumbs'].push(txt);
			} else {
				var txt = '<span class="open">'+i+'</span>';
				_cache['crumbs'].push(txt);
			}
		}
		
		if (count(_cache['crumbs'])>0) {
			this.no_crumbs	= false;
		} else {
			this.no_crumbs	= true;
		}
		
		_cache['crumbs_txt']	= _cache['crumbs'].join(' &gt; ');
	}
	
	/** когда кликаем по крошкам вызывается сначала эта функция а уже потом действией которое было задано в шаблоне */
	t.crumbsClick	= function(id) {
		if (typeof datastore['actions'][id]!=='undefined') {
			datastore['actions'][id]();
		}
	}
	
	/** заголовок для локации */
	t.setTitle	= function(title) {
		_cache['title']		= title;
	}
	
	/** возращает данные из кеша, впрочем как и везде :) */
	t.getInfo	= function(key) {
////		log(key);
////		log(_cache[key]);
////		log(_cache['title']);
//		for (var i in _cache) {
//			log(i.title);
//			log('123');
//		}
//		return;
		
		if (typeof _cache[key]!='undefined')
			return _cache[key];

		return key;
	}
	
	/** */
	t.overlayHide	= function() {
		$(this.path.overlay).fadeOut("fast");
	}
	
	/** */
	t.overlayShow	= function() {
		$(this.path.overlay).fadeIn("fast");
	}
	
	/** */
	t.overlay6Show	= function() {
		if (!$('#overlay_lPopup').hasClass('path_1'))
			$('body').append('<div id="overlay_lPopup" class="path_1"></div>');
	}
	
	/** */
	t.overlay6Hide	= function() {
		$('#overlay_lPopup').remove();
	}
	
	/** показываем после загрузки основногор  экрана */
	t.afterShow	= function() {
		//log('after_show');
		//return;
		if (typeof _cache['after_show']!='undefined' && typeof _cache['after_show'] == 'function') {
			var bb	= _cache['after_show'];
			_cache['after_show']	= function() {};
			bb();
		}
		_cache['after_show']	= function() {};
		
		autoSize();
	}
	
	/** */
	t.setAfterShow	= function(after) {
		_cache['after_show']	= after;
	}
	
	t.set		= function(key,value) {
		_cache[key]	= value;
	}
	
	/** переключаем */
	t.toggleShown	= function(key,obj) {
		if (PLAYER.shown.getInfo(key,1) == 1) {
			PLAYER.shown.set(key,0);
			$(obj).removeClass('open');
		} else {
			PLAYER.shown.set(key,1);
			$(obj).addClass('open');
		}
		
		t.initShown(key,0,200);
	}
	
	/** инициализируем shown элемент */
	t.initShown	= function(key,def,animate) {
		if (typeof animate == 'undefined') 
			animate	= 0;
		
		if (typeof def	== 'undefined')
			def	= 1;
		
		if (PLAYER.shown.getInfo(key,def) == 1) {
			
			if (typeof _cache.height == 'undefined' || typeof _cache.height['shown_'+key] == 'undefined')
				return ;
			
			$('.shown_'+key).addClass('opened');
			$('.shown_'+key).removeClass('closed');
			$('.shown_'+key).animate({'height':_cache.height['shown_'+key]},animate,function(){
				$(this).css("height", "auto");
				autoSize();
			});
		} else {
			if (typeof _cache.height == 'undefined')
				_cache.height	= {};
			
			_cache.height['shown_'+key]	= $('.shown_'+key).height();
			$('.shown_'+key).animate({'height':0},animate,function(){
				$(this).removeClass('opened');
				$(this).addClass('closed');
				autoSize();
			});
		}
	}
	
	/** возвращает либо */
	t.openIfShown	= function(key,def) {
		if (PLAYER.shown.getInfo(key,def) == 1) {
			return 'open';
		} else {
			return '';
		}
		
		return '';
	}
	
	/** обработчик цены и блоков цены */
	t.price		= priceHandler(t);
	function priceHandler(self) {
		var t	= {
			'self'	: self
		}
		
		var _cache	= {
			click_list	: {}
		};
		
		/** вовзращает блок с ценой */
		t.getBlock	= function(price,prefix,on_click) {
			prefix	= prefix || '';
			on_click = on_click || function() {};
			
			var id	= mt_rand(0,time());
			var info		= {
				'price'		: price,
				'price_title'	: ''
			}

			_cache.click_list[id]	= on_click;
			/**
				* price - представляет из себя объект вида: {
				*	type1 : {
				*		'money1':100,
				*		'sp_slaves': 15,
				*	},
				*	type2 : {
				*		'money3':10,
				*		'money10': 150
				*	}
				* }
				* 
				* Данный пример илюстрирует покупку либо за золото и работв, либо за зелень и пирашки
				* */
			var money_list	= [];
			var money_txt	= '';
			if (count(info.price)> 1) {
				var cache_key	= _getPriceCacheKey(info.price);
				var cache_value	= getSettings(cache_key,'');
				//log(cache_value);

				for (var type in info.price) {
					var checked	= '';
					var icon_block	= ''; 
					for (var money_ico in info.price[type]) {
						icon_block	+= info.price[type][money_ico] + ' ' + g('icon.'+money_ico);

						if (cache_value!='' && typeof info.price[cache_value]!='undefined') {
							if (cache_value == type) 
								checked = 'checked = "checked"';
						} else {
							/** активация валюты по умолчанию */
							if (money_ico == 'money1' || money_ico == "money2")
								checked = 'checked = "checked"';
						}
					}

					var money_block	= '<input type="radio" onclick="SKIN.price.setCache(\''+cache_key+'\',\''+type+'\',\''+id+'\')" name="price_type'+prefix+'" value="'+type+'" '+checked+'>'+icon_block;
					money_list.push(money_block);
				}

				money_txt	= money_list.join('&nbsp;\\&nbsp;');
			} else {
				for (var type in info.price) {
					var icon_block	= ''; 
					for (var money_ico in info.price[type]) {
						if (info.price[type][money_ico] == 0) {
							icon_block	+= '<div class="mt10 mb5">Первый раз &mdash; <span class="bold">бесплатно</span></div>';
						} else {
							icon_block	+= info.price_title + digit(info.price[type][money_ico]) + ' ' + g('icon.'+money_ico);
						}
					}

					var money_block	= '<input type="hidden" name="price_type'+prefix+'" value="'+type+'" >'+icon_block;
					money_list.push(money_block);
					money_txt	= money_list.join('&nbsp;\\&nbsp;');
				}

				money_txt	= money_list.join('');
			}

			/** взвращает хеш ключа цены */
			function _getPriceCacheKey(ar_price) {
				var key	= '';
				for (var type in ar_price) {
					for (var money_ico in ar_price[type]) {
						key = key + '' + money_ico;
					}
				}
				return key;
			}

			return money_txt;
		}
		
		/** возвращает выбраный тип цены */
		t.getSelected	= function(where,prefix) {
			prefix		= prefix || '';
			where		= where || SKIN.path.popup;
			var price	= $(where).find('input[name=price_type'+prefix+']:checked').val();
			if (typeof price === 'undefined' || price == '') {
				price	= $(where).find('input[name=price_type'+prefix+']').val();
			}
			return price;
		}
		
		/** сохраняет выбранную цену */
		t.setCache	= function(key,type,id) {
			setSettings(key,type);
			_cache.click_list[id](type);
		}
		
		return t;
	}
	
//	t.priceBlock	= function(price) {
//		
//	}
//	
//	
//	t.getSelectedPrice	= function() {
//		
//	}


	/** 
	 *  --------------------------------------------------------------------
	 *			PRIVATE FUNCTION 
	 *  --------------------------------------------------------------------
	 **/
	function _popupPos(path,correct,after) {
		correct.top	= correct.top || 0;
		var th	= this;
		
		var pos		= function(winHeight,scroll) {
			//log(winHeight,scroll);
			if (jQuery("body").height() < winHeight)
				winHeight	= jQuery("body").height();
		
			//log(winHeight,scroll);
			var height		= $(path).height();
			var result		= winHeight/2 - height/2 ;
			var ttop		= limit(scroll+result+correct.top,40);
			
			/** фикс - если надо спозиционировать по уровню элемента */
			var obj			= GLOBAL.getObj();
			if (typeof obj != 'undefined' && obj != false) {
				var content_off	= $(obj).offset();
				log(content_off);
				if (typeof content_off != 'undefined' && typeof content_off.top !='undefined') {
					ttop	= limit(content_off.top-(height/2)+correct.top,40,document.getElementById('content').clientHeight - height -40);
				}
			}
			
//			log(height);
//			log(result);
//			log(winHeight);
//			log(scroll);
//			log('asd');
			jQuery(path).css({marginTop: '' + parseInt(ttop) + 'px'});
			after();
		}
		
		if (SERVER_OS == 'vk') {
			VK.addCallback('onScrollTop', function(scroll,windowsHeight) {pos(windowsHeight,intval(scroll)-100);});
			VK.callMethod('scrollTop'); // вызывали метод получения скрола, он же установит топ нашему алерту
		} else {
			//var scroll		= getBodyScrollTop();
			var scroll		= 0;
			var windowsHeight	= getClientHeight();
			pos(windowsHeight,scroll);
		}
	}
	
	
	return t;	
}

/** 
 *-------------------------------------------------------------------   
 *                       Actions
 *-------------------------------------------------------------------   
 **/
function actionsHandler() {
	var t           = {};
	var bool_flag    = true;
        
	t.profile	= profileHandler(t);
	function profileHandler(self) {
		var t	= {};
		t.self	= self;
		
		/** показываем экран регистрации вместе с шаблном first */
		t.screenRegister	= function() {
			/** порядок действий: 
			 * 1. Получаем шаблон регистрации
			 * 2. Вписываем шаблон рег в шаблон first
			 * 3. Выводим все это в content
			 **/
			
			SKIN.first(SKIN.parse('profile/register/register_main'));
		}
		
		/** показываем экран игрока вместе с шаблоном main */
		t.screenMain		= function(param) {	
			var ok	= function(r) {
				/** формируем переменные для показа */
				var vars	= {
						'info'		: {
							'avatar'		: PLAYER.profile.getInfo('avatar'),
							'name'			: PLAYER.profile.getInfo('name'),
							'race'			: PLAYER.profile.getInfo('race'),
							'sex'			: PLAYER.profile.getInfo('sex'),
							'life_energy_percent'	: PLAYER.profile.getInfo('life_energy_percent'),
							'exp_percent'		: PLAYER.profile.getInfo('exp_percent'),
							'level'			: PLAYER.profile.getInfo('level')
						},
						'vars'		: {
							'ar_all_ordens'		: _getOrdensHtml(),
							'ar_all_medals'		: _getMedalsHtml(),
							'swag'			: r.swag
						},
						'param'				: param
				}
				SKIN.main(SKIN.parse('profile/player/player_main',vars),SCREEN_PROFILE);
				SKIN.profile.reload();
			}
			
			API.call('profile.getInfo',{'need':'profile,pet,items,house,gifts,ordens,medals,money,effects'},ok);
			
			/** HTML массив с орденами */
			function _getOrdensHtml() {
				var ar_now	= PLAYER.ordens.getInfo();
				var ar_all_ordens	= [];
				var limit	= 24;

				for(var b in ar_now) {
					var txt	= '<div class="square active_square medal fl_l orden orden_{ID}" title="" onclick="GLOBAL.honor.showOrden(\'{ID}\')" onmouseover="TOOLTIP.show(this,{\'type\':\'ordens\',\'tooltip_id\':\'orden_{ID}\'});"></div>'.format({'ID':ar_now[b]});
					ar_all_ordens.push(txt);
				}

				/** дополняем пустыми полями */
				for (var a = count(ar_all_ordens); a<=limit;a++) {
					var txt	= '<div class="square active_square fl_l pointer"></div>';
					ar_all_ordens.push(txt);
				}

				return ar_all_ordens;
			}

			/** HTML массив с медалями */
			function _getMedalsHtml() {
				var ar_now		= PLAYER.medals.getInfo();
				var ar_all_medals	= [];
				var limit	= 24;
				for (var a=6;a>=1;a--) {
					for(var b in ar_now[a]) {
						var txt	= '<div class="square active_square medal fl_l level_{LEVEL}_1 medal_{ID}" title="" onclick="GLOBAL.honor.showMedal(\'{ID}\',\'{LEVEL}\')" onmouseover="TOOLTIP.show(this,{\'type\':\'medals\',\'tooltip_id\':\'medal_{LEVEL}_{ID}\'});"></div>'.format({'LEVEL':a,'ID':ar_now[a][b]});
						ar_all_medals.push(txt);
					}
				}

				/** дополняем пустыми полями */
				for (var a = count(ar_all_medals); a<=limit;a++) {
					var txt	= '<div class="square active_square fl_l pointer"></div>';
					ar_all_medals.push(txt);
				}

				return ar_all_medals;
			}
		}
		
		/** экрана забаненого игрока */
		t.screenBan		= function() {
			SKIN.main(SKIN.parse('profile/player/player_ban'),SCREEN_BAN);
			SKIN.profile.reload();
		}
		
		t.screenGifts		= function() {					
			SKIN.main(SKIN.parse('profile/player/player_gifts'));			
		}				
							
		t.training		= trainingHandler(t);
		function trainingHandler(self) {
			var t	= {};
			t.self	= self;
			var _cache  = {
				'start'		: {},
				'delta'		: {},
				'start_percent'	: {}
			}
			
			t.showPopup	= function(from_popup) {
				
				/**  получаем текущие данные с сервера*/
				var ok		= function(r) {			
					
					if (typeof from_popup !='undefined' && from_popup == true) {
						// только что прокачались
						from_popup	= true;
					} else {
						// вызвали попап из кнопки
						from_popup	= false;
					}

					var vars	= r;
					var max		= 0;	
					var data	= r.training_money1.stats;
							
					/** находим макс */
					for(var key in data){
						var value = data[key];	//value равен значения, а key = (power, block...)
						
						for(var key2 in value) {
							var value2 = value[key2]; //value2 равен значениям (50, 10, 40), key2 = active, now, price
							if (key2 == 'now') {								
								if(max < intval(value2)){
									var max = intval(value2);
								}
								
								/** если из кнопки - запоминаем start */
								if (!from_popup) {
									_cache['start'][key]	=  value2;
								}
								
								/** разсчитываем сколько зеленых квадратов показать */
								if (typeof vars['delta'] == 'undefined')
									vars['delta']	= {};
								
								vars['delta'][key]	= value2 - _cache['start'][key];
							}
						}												
					}	
					
					/** присваиваем проценты */										
					for(var key in data){	
						/** выситываем проценты только при первой инициализации, а дальше берем их из кеша */
						if (!from_popup) {
							_cache['start_percent'][key]	= intval(vars['training_money1']['stats'][key]['now'] / (max / 75));
						}
						
						vars['training_money1']['stats'][key]['percent'] = _cache['start_percent'][key];
						vars['training_money1']['stats'][key]['price']	= digit(vars['training_money1']['stats'][key]['price']);					
					}										
					
					/** при закрытии popup обновляем окно игрока */
					SKIN.popupShow(SKIN.parse('profile/player/player_training',vars),function() {
						if (SKIN.nowScreen() == SCREEN_PROFILE) {
							ACTIONS.profile.screenMain();
							return true;
						}
					},POPUP_TRAINING);
//					$(SKIN.path.popup).addClass('top240');
				}
				
				API.call('profile.getTrainingInfo',{},ok);
				// если хотим перекрыть - API.call('training.getInfo',{},ok);
				
			} // shopPopup			
			/** пытаемся прокачаться на золото */
			t.tryByGold		= function(key) {
				var ok		= function(r) {
					ACTIONS.profile.training.showPopup(true);
				}
				
				var error	= function(r) {
					if (r.code == ERROR_CODE_NO_MONEY) {
						lAlertNoMoney();
					}
				}
				
				API.call('profile.doTraining',{'stat':key},ok,error);
			}
			
			/** пытаемся прокачаться за рыбы */
			t.tryByFish		= function() {
				alert('Пытаемся прокачаться за рыбу');
			}
			
			/** по клику на плюc - увеличиваем значение на 1*/
			t.incStatByFish		= function() {
				
			}
			
			/** по клику уменьшаем на 1 от прокачки */
			t.decStatByFish		= function() {
				
			}
			
			/** возращает стоимость прокачки на 1 за пирашки */
			t.getFishPrice		= function() {
				return 1;
			}
			
			t.updateCollnes		= function() {
				
			}
						
			/** 
			 *- ----------------------------------------------------
			 *		Функции расчета из старой ботвы
			 *- ----------------------------------------------------
			 **/
			function recountFish(){

				var total	= 0 ;
				var total_price	= 0 ;
				var val,price=0;

				for(key in prices){
					val	= parseInt($('#'+key).val());


					price	= Math.ceil(getFishPrice(key,val));

					$('#price_'+key).html(price);

					doCoolness(key,val);

					total	+= val;
					total_price	+= price;

				}
				$('#total').html(total);
				$('#total_price').html(Math.ceil(total_price));
				$('#total_price2').html(Math.ceil(total_price));

				if (total_price>have_fish)
					$('#not_enought').show();
				else
					$('#not_enought').hide();

			}
			/**
			 *
			 * @access public
			 * @return void
			 **/
			function doCoolness(key,add){
				var config	= prices[key];

				var level	= doCoolnessLevel(config[1]+add,config[3],config[4]);

				var string	= "";

				var n=1;

				for(;n <= level;n++)
					string	+= coolness;

				for(;n <=5 ;n++)
					string	+= coolness2;


				$('#coolness_'+key).html(string);

				return level;
			}
			/**
			 *
			 * @access public
			 * @return void
			 **/
			function doCoolnessLevel(now,min,max){
				Z	= (max-min)/5;

				if (now	<=	(min+Z))
					return 1;
				else if (now	<=	(min+Z*2))
					return 2;
				else if (now	<=	(min+Z*3))
					return 3;
				else if (now	<=	(min+Z*4))
					return 4;
				return 5;
			}
			function getFishPrice(key,add){
				var config	= prices[key];

				var total	= 0;

				for(var n=1;n<=add;n++){
					total	+= getFishPriceItem(config,config[1]+n);
				}
				return total;
			}
			/**
			 *
			 * @access public
			 * @return void
			 **/
			function getFishPriceItem(config,stat){
			//	var statK = Math.max(1,config[0] / 2.2);
				var statK = 4.72;
				var ratio = stat / config[2];

				var diff	= (stat - config[2])/config[2]*100;

				var extra	= 1;
				if (diff>40) {
					diff	= diff-40;
					extra	+= Math.floor(diff/5)*0.2;

				}

				var coolnessLevel = doCoolnessLevel(stat,config[3],config[4]);

				if (typeof harbourTraining != "undefined" && harbourTraining == 1){
					if (coolnessLevel <= 3)
						statK = statK * 0.65;
					if (coolnessLevel >= 4)
						statK = statK* 1.30;				
				}

				var cost = (Math.pow(2, ratio) - 1) * (Math.pow(3, ratio) - 1) * 3.3 * config[0]*statK*extra;
				cost*=10;
				var discount	= 1;
				if (typeof fish_multy != 'undefined')
					discount	= fish_multy;

				return Math.ceil(cost*discount);
			}
			
			return t;
		}
		
		/** выбор аватара и регистрация нового персонажа */
		t.regAvatarSelector	= function() {
			var t	= {};

			t.init	= function(config) {
				//log(config);
				this.avatars	= config.avatars || {};
				this.sex		= config.sex || 1;
				this.race		= config.race || 1;

				this.current	= 0;
				this.base	= '#avatar_selector';
				this.path	= {
				    avatar: this.base + ' .avatar',
				    sex1	: '#sex1',
				    sex0	: '#sex0',
				    ava_left: this.base + ' #ava_left',
				    ava_right: this.base + ' #ava_right',
				    race0	: '#race0',
				    race1	: '#race1'
				};

				this.bind();
				this.show();
				this.validateSex();
			}

			t.bind	= function() {
			    var self = this;

			    $(this.path.ava_left).click(function() {self.prev();self.show();});
			    $(this.path.ava_right).click(function() {self.next();self.show();});

			    $(this.path.sex0).click(function() { 
				    self.setSex(0); 
				    self.show();
			    });
			    $(this.path.sex1).click(function() {
				    self.setSex(1); 
				    self.show();
			    });

			    $(this.path.race1).click( function() {self.setRace(1);self.show();});
			    $(this.path.race0).click( function() {self.setRace(0);self.show();});

			}

			t.validateSex	= function() {
			    if (this.sex == 1) {
				    $(this.path.sex1).addClass('selected');
				    $(this.path.sex0).removeClass('selected');
			    } else {
				    $(this.path.sex0).addClass('selected');
				    $(this.path.sex1).removeClass('selected');
			    }
			}

			t.validateRace	= function() {
			    if (this.race == 1) {
				    $(this.path.race1).addClass('selected');
				    $(this.path.race0).removeClass('selected');
			    } else {
				    $(this.path.race0).addClass('selected');
				    $(this.path.race1).removeClass('selected');
			    }
			}

			t.show	= function() {
			    this.validateRace();
			    this.validateSex();

			    var url	= 'url('+ this.get() +')';
			    $(this.path.avatar).css('background', url);

			    var r	= this.get();
			    r	= r.substring(r.lastIndexOf('/')+2, r.lastIndexOf('.'));
			    $(':input[name=avatar]').val(r);
			}

			t.get	= function() {
			    if (this.current == -1)
				    this.current	= 0;

			    return ADATA_URL + '/avatars/n' + this.avatars[this.race][this.sex][this.current] + '.jpg';
			}

			/** волзращает id аватара для регистрации */
			t.getId	= function() {
			      if (this.current == -1)
				    this.current	= 0;

			    return this.avatars[this.race][this.sex][this.current];
			}

			t.next	= function() {
			    this.current++;

			    if (typeof this.avatars[this.race][this.sex][this.current] == 'undefined') {
				    this.current	= 0;
			    }
			}

			t.prev	= function() {
			    this.current--;
			    if (typeof this.avatars[this.race][this.sex][this.current] == 'undefined') {
				    for (i in this.avatars[this.race][this.sex]);
				    this.current	= i;
			    }
			}

			t.setSex	= function(sex) {
			    this.sex	= sex;
			}

			t.setRace	= function(id) {
			    this.race	= id;
			}

			return t;
		} // profileHandler
		
		/** временно показыаем профиль */
		t.showAboutTemp		= function() {
			var vars	= {
				'info'		: {
					'avatar'	: PLAYER.profile.getInfo('avatar'),
					'name'		: PLAYER.profile.getInfo('name'),
					'race'		: PLAYER.profile.getInfo('race'),
					'sex'		: PLAYER.profile.getInfo('sex'),
					'life_energy_percent' : PLAYER.profile.getInfo('life_energy_percent'),
					'exp_percent'	: PLAYER.profile.getInfo('exp_percent'),
					'level'		: PLAYER.profile.getInfo('level')
				}
			};
			SKIN.popupShow(SKIN.parse('profile/player/player_about',vars));
		}
		
		t.addPotion		= function(id,max) {
//			lPopupRemove();
//	
//			SKIN.set(ON_CLOSE_POPUP,function(){
//				ACTIONS.profile.screenHeal();
//			});
//
//			ACTIONS.shop.items.show(num,{'afterBuy':function(){ 
//					SKIN.profile.reloadPotion(); 
//					ACTIONS.profile.screenHeal();
//					bPopupRemoveForce();
//			}});	
		
			var data = {
				'price_type'	: SKIN.price.getSelected('#price_block_potion_'+id),
				'id'		: id,
				'type'		: 'items',
				'max'		: typeof max == 'undefined' ? false : max
			}

			var th	= this;
			API.call('shop.buy',data,function(r){
				ACTIONS.profile.screenHeal();
				bOk(g('global.potion_buy_ok'));
			},function(r){
				if (r.code == 10)
					return noMoney();
				bAlert(g('error.shop_'+r.code));
			});
		}
		
		/** выпить бутылочку - лечебные + оборотку */
		t.usePotion		= function(id) {
			/** А есть ли бутылочки?  */
			if (PLAYER.specials.getInfo('potion_'+id) < 1) {
				bAlert(g('error.profile_8'));
				return ;
			}
			
			var ok		= function(r) {
				bOk(r.message);
				SKIN.profile.reload();
				ACTIONS.profile.screenHeal();
			}
			
			var error	= function(r) {
				if (r.code == 12) {
					bAlert(g('error.profile_'+r.code,{'END':r.end}));
				} else {
					bAlert(g('error.profile_'+r.code));
				}
			}
			
			API.call('profile.usePotion',{'id':id},ok,error);
		}
		
		/** показываем окно настройки персонажа */
		t.screenSetup		= function() {
			SKIN.main(SKIN.parse('profile/player/player_setup'),SCREEN_SETUP);
		}
		
		/** превью страницы персонажа в настройках */
		t.screenAboutPreview	= function() {
			var ok		= function(r) {
				
				var vars	= {
					'vars'	: {
						'about_html'	: r.about_html
					}
				}
				SKIN.popupShow(SKIN.parse('profile/player/player_setup_preview',vars));
			}
			
			var info	= {
				'about'		: $('#description_text').val()
			};
			
			API.call('profile.previewAbout',info,ok,ok);
		}
		
		/** сохраняем настройки социальности */
		t.saveSocialSetup	= function() {
			var info	= {
				'age'		: $('#tutorial_settings_1').val(),
				'city'		: $('#tutorial_settings_2').val()
			};
			
			/** ок сохранили */
			var ok		= function(r) {
				bOk(g('profile.save_setup_ok'));
			}
			
			/** возможные ошибки */
			var error	= function(r) {
				
			}
			
			API.call('profile.saveSocialSetup',info,ok,error);
		}
		
		/** схораняем описание для нападения */
		t.saveAboutSetup	= function() {
			var info	= {
				'about'		: $('#description_text').val()
			};
			
			/** ок сохранили */
			var ok		= function(r) {
				bOk(g('profile.save_setup_ok'));
			}
			
			/** возможные ошибки */
			var error	= function(r) {
				
			}
			
			API.call('profile.saveAboutSetup',info,ok,error);
		}
		
		/** начать заново туториал */
		t.clearTutorial	= function() {
			var set	= {};
			for (var key in JS_TUTORIAL_ALLOW) {
				set[JS_TUTORIAL_ALLOW[key]] = 0;
			}
			
			setSettingsPack(set);
			bOk(g('profile.save_setup_ok'));
			GLOBAL.reloadPage();
		}
		
		/** завершить туториал */
		t.endTutorial	= function() {
			var set	= {};
			for (var key in JS_TUTORIAL_ALLOW) {
				set[JS_TUTORIAL_ALLOW[key]] = 1;
			}
			
			PLAYER.jsSettings.setPack(set,function(){
				bOk(g('profile.save_setup_ok'));
				GLOBAL.reloadPage();
			});
		}
		
		/** экран с аватарами */
		t.screenAvatar		= function(page,type,mode,force) {
			/** заносим в локальный кеш данный по которым показывали */
			GLOBAL.set('screenAvatar',{'page':page,'type':type,'mode':mode});
			
			var ok		= function(r) {
				var vars	= {
					'vars'	: {
						list		: r.list,
						price		: r.price,
						pages		: r.pages,
						base_avatar	: r.base_avatar,
						now_page	: typeof page == 'undefined' ? 1 : page,
						now_type	: r.now_type
					}
				}
				
				SKIN.main(SKIN.parse('profile/player/player_avatar',vars),SCREEN_AVATAR);
			}
			
			API.call('profile.getAvatarList',{'page':page,'type':type,'mode':mode},ok);
		}
		
		/** пробуем установить выбранный аватар */
		t.doAvatar		= function() {
			var info	= GLOBAL.get('screenAvatar');
			if (typeof info.type=='undefined')
				return false;
			
			var ok		= function(r) {
				ACTIONS.profile.screenAvatar(info.page,info.type,info.mode,true);
				bOk(g('profile.do_avatar_ok'));
			}
			
			var error	= function(r) {
				if (r.code == ERROR_CODE_NO_MONEY) {
					lAlertNoMoney();
				}
			}
			
			API.call('profile.doAvatar',{'type':info.type},ok,error);
		}
		
		/** показываем экран levelup */
		t.screenLevelup		= function(level,user_id) {
			var ok		= function(r) {
				var vars	= {
					'vars'	: {
						animate		: PLAYER.profile.getInfo('redirect') == SCREEN_LEVELUP ? 1 : 0,
						medals_list	: _getMedalsList(r.medals),
						info		: r.info,
						stat		: r.stat,
						link		: APP_URL + '#up'+r.info.user_id + '_' + r.info.level
					}
				}
				SKIN.main(SKIN.parse('profile/player/player_levelup',vars),SCREEN_LEVELUP);
			}
			
			var error	= function(r) {
				if (r.code == 11) {
					/** если levelup не найден - очищаем его*/
					ACTIONS.profile.clearLevelup();
				}
			}
			
			API.dontCheckRedirect	= true;
			API.call('profile.getLevelupInfo',{'user_id':user_id,'level':level},ok,error);
			
			/** 
			 *	-----------------------------------------------
			 *			PROTECTED
			 *	-----------------------------------------------
			 */
			function _getMedalsList(list) {
				var output	= [];

				for (var key in list) {
					var value	= list[key];
					if (value.type == 'medal') {
						var txt	= '<div class="square active_square medal fl_l level_{LEVEL}_1 medal_{ID}" title="" onclick="GLOBAL.honor.showMedal(\'{ID}\',\'{LEVEL}\')" onmouseover="TOOLTIP.show(this,{\'type\':\'medals\',\'tooltip_id\':\'medal_{LEVEL}_{ID}\'});"></div>'.format({'LEVEL':value.level,'ID':value.id});
					} else {
						var txt	= '<div class="square active_square medal fl_l orden orden_{ID}" title="" onclick="GLOBAL.honor.showOrden(\'{ID}\')" onmouseover="TOOLTIP.show(this,{\'type\':\'ordens\',\'tooltip_id\':\'orden_{ID}\'});"></div>'.format({'ID':value.id});
					}

					output.push(txt);
				}

				/** дополняем пустыми полями */
				for (var a = count(output); a<=24;a++) {
					var txt	= '<div class="square active_square fl_l pointer"></div>';
					output.push(txt);
				}

				return output;
			}
		}
		
		/** очищаем редирект при levelup */
		t.clearLevelup		= function() {
			var ok	= function() {
				ACTIONS.profile.screenMain();
			}
			
			API.call('profile.clearLevelup',{},ok,ok);
		}
		
		/** игрок кликну по полоске с рейтингом - показываем информацию о рейтинге и место игрока* */
		t.screenRatingInfo	= function() {
			var ok		= function(r) {
				var vars	= {
					'vars'	: {
						'info'	: r.info
					}
				}
				var txt	= SKIN.parse('profile/profile_rating_info_alert',vars);
				var p	= popup();

				p.add({
					'message'	: txt,
					'title'		: 'Рейтинг',
					'width'		: 400
				}).show();
			}
			
			API.call('profile.getRatingInfo',{},ok);
		}
		
		/** показываем экран выбора наставника */
		t.checkTeacher		= function() {
			if (PLAYER.profile.getInfo('teacher_id')>0 || PLAYER.profile.getInfo('teacher_id')== -1)
				return false;
			
			/** если нет друзей -ставим учителя -1 */
			var list	= PLAYER.social.getInfo('friends_app');
			if (count(list) < 1) {
				API.call('profile.setTeacher',{'id':-1});
				return false ;
			}
			
			/** если есть друзья - просим выбрать того, кто пригласил */
			var vars	= {
				'vars'	: {
					'list':	list
				}
			};
			SKIN.popupShow(SKIN.parse('profile/profile_check_teacher_popup',vars));
			
		}
		
		/** когда кликнули выбрать учителя */
		t.setTeacher		= function(user_id) {
			var load	= function(r) {
				SKIN.popupClose();
			}
			API.call('profile.setTeacher',{'id':user_id},load,load);
		}
		
		/** обновляем список друзей кто установил это приложение */
		t.updateFriendInGame	= function() {
			
			/** для контакта и локальный список */
			if (SERVER_OS == 'vk' || SERVER_OS == 'local') {
				log('updateFriendInGame...');
				var ok		= function(data) {
					if (count(data) > 0) {
						API.call('social.updateFriendsInApp',{list:data});
					}
				}

				SOCIAL.friends.getInApp(ok);
			}
			
			/** получаем список друзей для одноклассников и зановим их туда */
			if (SERVER_OS == 'ok') {
				log('updateFriendInGame...');
				API.call('ok.getFriendsInGame',{data:GLOBAL.data});
			}
			
			/** получаем список друзей для одноклассников и зановим их туда */
			if (SERVER_OS == 'mir') {
				log('updateFriendInGame...');
				API.call('mir.getFriendsInGame',{data:GLOBAL.data});
			}
			
			
		}
		
		/** обновляем социальное имя, фамилию, фотку, аватар */
		t.updateSocialInfo	= function() {
			/** для контакта и локальный список */
			if (SERVER_OS == 'vk' || SERVER_OS == 'local') {
				log('updateSocialInfo...');
				var onload	= function(data) {
					API.call('social.updateMyInfo',data);
				}

				SOCIAL.info.getMain(onload);
			}
			
			/** получаем список друзей для одноклассников и зановим их туда */
			if (SERVER_OS == 'ok') {
				log('updateSocialInfo...');
				API.call('ok.updateMySocialInfo',{data:GLOBAL.data});
			}
			
			/** получаем список друзей для одноклассников и зановим их туда */
			if (SERVER_OS == 'mir') {
				log('updateSocialInfo...');
				API.call('mir.updateMySocialInfo',{data:GLOBAL.data});
			}
		}
				
		/** экран бутылочек - 3 бутылки */
		t.screenHeal		= function() {
			var ok	= function(r) {
				var vars	= {
					vars	: {
						price	: {
							'potion_1'	: SKIN.price.getBlock(r.list['item_1'].price),
							'potion_2'	: SKIN.price.getBlock(r.list['item_2'].price),
							'potion_3'	: SKIN.price.getBlock(r.list['item_3'].price)
						}
					}
				}
				
				//log(vars);
				
				var txt	= SKIN.parse('profile/profile_heal_popup',vars);
				var p	= popup();

				p.add({
					'message'	: txt,
					'title'		: 'Зелья',
					'simple'	: true,
					'width'		: 400
				}).show();
			}
			
			API.call('shop.getPriceHeal',{},ok);
		}
		
		/** экран настроек профиля (раса, пол и имя) */
		t.screenSettings	= function() {
			var vars	= {	
				'sex' : PLAYER.profile.getInfo('sex'),
				'race' : PLAYER.profile.getInfo('race'),
				'name' : PLAYER.profile.getInfo('name')
			}

			var txt	= SKIN.parse('profile/profile_setup_popup',{'vars':vars});
			var p	= popup();

			p.add({
				'message'	: txt,
				'title'		: 'Настройка профиля',
				'simple'	: true,
				'width'		: 454
			}).show();
		}
		
		/** сохраняем измененные данные профиля (раса, пол и имя) */
		t.saveProfileSettings	= function() {
			var ok		= function(r) {
				bOk('Данные сохранены');
				ACTIONS.profile.screenMain();
				
				var race	= PLAYER.profile.getInfo('race') == 0 ? 'Барантус' : 'Свинтус';
				var sex		= PLAYER.profile.getInfo('sex') == 0 ? 'Женский' : 'Мужской';
				var name	= PLAYER.profile.getInfo('name');
				
				//log('Пол: '+sex+', Раса: '+race+', Имя: '+name);
			}
			
			var error	= function(r) {
				if (r.code == 10) {
					noMoney();
					return false;
				}
				
				bAlert('error.profile_'+r.code);
			}
						
			var data	= {
				'name'		: $('#data_name').val(),
				'race'		: $('#data_race').val(),
				'sex'		: $('#data_sex').val()			
			}
			
			API.call('profile.doSaveProfile',data,ok,error);
		}
		
		/** сохраняем настройки */
		t.saveOtherSetup	= function() {
			var info	= {
				'show_social'	: $('#path_show_social').val(),
				'flag_plant'	: $('#path_flag_plant').val()
			}
			
			/** ок сохранили */
			var ok		= function(r) {
				bOk(g('profile.save_setup_ok'));
				setSettings(JS_SETTINGS_VIDEO,$('#path_video').val());
				setSettings(JS_SETTINGS_ANIMATE,$('#path_log_animate').val());
				setSettings(JS_SETTINGS_MENU,$('#path_menu').val());
				ACTIONS.profile.screenSetup();
			}
			
			/** возможные ошибки */
			var error	= function(r) {
				
			}
			
			API.call('profile.saveOtherSetup',info,ok,error);
		}
		
		/** добавляем ссылку в меню слева */
		t.setLeftMenu		= function() {
			SOCIAL.info.checkLeft(function(){
				API.call('profile.leftMenuOk',{},function(){
					bOk(g('global.menu_left_ok'),5000);
					ACTIONS.profile.screenMain();
				});
			});
		}
		
		return t;
	}		
	
	t.fight		= fightHandler(t);
	function fightHandler(self) {
		var t	= {};
		t.self	= self;
		
		/** показываем экран "бодаться" */
		t.screenMain		= function() {	
			var th			= this;
			var watch_time_interval	= 10; // кол-во минут в одном интервале дозора
			
			/** ok */
			var ok		= function(r) {
				var vars	= {
					'vars' : {
						'watch'	: {
							'available_time'	: r.watch.available_interval * watch_time_interval,
							'last_prize'		: r.watch.last_prize,
							'price'			: r.watch.price,
							'price_type'		: r.watch.price_type,
							'available_interval'	: r.watch.available_interval,
							'watch_time_interval'	: watch_time_interval
						},
						/** информация для блока напасть */
						'fight'	: {
							'can_fight'		: r.fight.can_fight,
							'timer_attack_by'	: r.fight.timer_attack_by,
							'price'			: r.fight.price,
							'price_type'		: r.fight.price_type,
							'last_prize'		: r.fight.last_prize,
							'restriction'		: r.fight.restriction
						}
					}
				};
				
				SKIN.main(SKIN.parse('fight/fight_main',vars),SCREEN_FIGHT);
			}
			
			/** ошибка */
			var error	= function(r) {
				if (r.code == 36) {
					//th.screenBuyPotions();
					lAlert(g('error.min_life_energy'));
					return ;
				}
				
				if (r.code == 35) {
					th.screenWatch();
					return ;
				}
			}
			
			API.call('fight.getInfo',{},ok,error);
		}
		
		/** кликнули по кнопке идти в дозор */
		t.doWatch		= function() {
			var th		= this;
			var interval	= $('#watch_select_interval').val();
			if (interval < 1) {
				bAlert({
					'title'	: g('error.fight_watch_no_time_title'),
					'text'	: g('error.fight_watch_no_time')
				});
				return ;
			}
			
			var data	= {
				'interval'	: interval
			}
			
			/** ok */
			var ok		= function(r) {
				th.screenWatch();
				return ;
			}
			
			/** error */
			var error	= function(r) {
				if (r.code == 36) {
					th.screenBuyPotions();
					return ;
				}
				
				if (r.code == 35) {
					th.screenWatch();
					return ;
				}
				
				/** на сегодня лимит дозора исчерпан */
				if (r.code == 32) {
					bAlert({
						'title'	: g('error.post_balert_error_title'),
						'text'	: g('error.fight_watch_no_time')
					});
					return;
				}
				
				if (r.code == 10) {
					lAlertNoMoney();
					return ;
				}
				
				/** игрок в клановом штурме */
				if (r.code == 31) {
					bAlert({
						'title'	: g('error.fight_watch_code_31_title'),
						'text'	: g('error.fight_watch_code_31')
					});
					return;
				}
				
				/** игрок работает  */
				if (r.code == 30) {
					bAlert(g('error.fight_watch_code_30'));
					return;
				}
			}
			
			API.call('fight.doWatch',data,ok,error);
		}
		
		/** 
		 * когда не достаточно энергии для драки, показываем окно с покупкой зелей 
		 * Действует для персон ниже 10 уровня (логика на сервере)
		 **/
		t.screenBuyPotions	= function() {
			var vars	= {
				'vars'	: {
					
				}
			}
			SKIN.main(SKIN.parse('fight/fight_buy_potion',vars));
		}
		
		t.screenLog		= function(log_id) {	
			
			/** ок - логи есть - показываем лог */
			var ok		= function(r) {						
				var vars	= r;	
				vars.log_id	= log_id;

				var my_max		= 0;
				var enemy_max		= 0;
				var my_data		= r.my_stats;
				var enemy_data		= r.enemy_stats;
				
				for(var my_key in my_data){
					var my_value = my_data[my_key];

					for(var my_key2 in my_value) {
						var my_value2 = intval(my_value[my_key2]);
						if (my_key2 == 'now') {
							if(my_max < my_value2){
								var my_max = my_value2;
							}
						}
					}												
				}	
				
				for(var enemy_key in enemy_data){
					var enemy_value = enemy_data[enemy_key];

					for(var enemy_key2 in enemy_value) {
						var enemy_value2 = intval(enemy_value[enemy_key2]);
						if (enemy_key2 == 'now') {								
							if(enemy_max < enemy_value2){
								var enemy_max = enemy_value2;
							}
						}
					}												
				}
				
				/** присваиваем проценты */										
				for(var my_key in my_data){			
					if (typeof vars['my_stats'][my_key].now !='undefined')
						vars['my_stats'][my_key]['percent'] = intval(vars['my_stats'][my_key]['now'] / (my_max / 100));
					
				}	
				
				for(var enemy_key in enemy_data){												
					if (typeof vars['enemy_stats'][enemy_key].now !='undefined')
						vars['enemy_stats'][enemy_key]['percent'] = intval(vars['enemy_stats'][enemy_key]['now'] / (enemy_max / 100));
					
				}
				
				/** корректируем аватары */
				var replace	= {
					'domain_url'	: getDomain(vars.my_block.info.user_id),
					'user_id'	: vars.my_block.info.user_id,
					'lang'		: g('global.show_profile'),
					'img_url'	: ADATA_URL + "/avatars/s"+vars.my_block.info.avatar+'.jpg'
				}
				var txt	= '<a href="{domain_url}" target="_top" onclick="return ACTIONS.showProfile(\'{user_id}\');" title="{lang}"><img width="156" height="200" class="" src="{img_url}" alt=""></a>';
				vars.my_avatar	= txt.format(replace);
				
				var replace	= {
					'domain_url'	: getDomain(vars.enemy_block.info.user_id),
					'user_id'	: vars.enemy_block.info.user_id,
					'lang'		: g('global.show_profile'),
					'img_url'	: ADATA_URL + "/avatars/s"+vars.enemy_block.info.avatar+'.jpg'
				}
				var txt	= '<a href="{domain_url}" target="_top" onclick="return ACTIONS.showProfile(\'{user_id}\');" title="{lang}"><img width="156" height="200" class="flip_horizontal" src="{img_url}" alt=""></a>';
				vars.enemy_avatar	= txt.format(replace);
				
				SKIN.main(SKIN.parse('fight/fight_log', {'vars':vars}));
				
				/** корректируем имена */
				var replace	= {
					'domain_url'	: getDomain(vars.my_block.info.user_id),
					'user_id'	: vars.my_block.info.user_id,
					'lang'		: g('global.show_profile'),
					'name'		: vars.my_block.info.name
				}
				var txt	= '<a href="{domain_url}" target="_top" onclick="return ACTIONS.showProfile(\'{user_id}\');" title="{lang}">{name}</a>';
				vars.my_name	= txt.format(replace);
				
				var replace	= {
					'domain_url'	: getDomain(vars.enemy_block.info.user_id),
					'user_id'	: vars.enemy_block.info.user_id,
					'lang'		: g('global.show_profile'),
					'name'		: vars.enemy_block.info.name
				}
				var txt	= '<a href="{domain_url}" target="_top" onclick="return ACTIONS.showProfile(\'{user_id}\');" title="{lang}">{name}</a>';
				vars.enemy_name	= txt.format(replace);
				
				
				/**
				 *	-----------------------------------
				 *		    ВЫВОДИМ
				 *	-----------------------------------
				 **/
				SKIN.main(SKIN.parse('fight/fight_log', {'vars':vars}));
				
				if (vars.have_video == 1 && getSettings(JS_SETTINGS_VIDEO,1)==1) {
					SKIN.popupShow(SKIN.parse('fight/fight_video_popup',vars),function(){
						TUTORIAL.onBind(JS_SETTINGS_TUTORIAL_BEGIN_STEP7, 'step11',{'skip':[SCREEN_PROFILE]});
					},SCREEN_LOG);					
				}
			}

			/** не можем показать лог - какие-то ошибки */
			var error	= function(r) {
				//log('Actions.screenLog = error: '  + r);
			}

			API.call('fight.getLog',{'log_id':log_id},ok,error);			
		}
		
		/** экран дозора, когда игрок в дозоре */
		t.screenWatch		= function(force,r) {	
			var force	= force || false;
			r		= r	|| null;
			/** если вызвали экран дозора а работы нет - принудительно обновляем работу */
			if (PLAYER.work.getInfo('work_type')!=WORK_TYPE_WATCH && r == null) {
				if (force)
					return ;
				
				API.call('profile.update',{need:'work'},function(){
					ACTIONS.fight.screenWatch(true);
				});
				return;
			}
			
			if (r	== null) {
				/* дозор идет */
				var vars	= {
					'vars'	: {
						'till'	: PLAYER.work.getInfo('work_end'),
						'type'	: 0
					}
				}
				
				//log('watch comming ...');
			} else {
				/** дозор окончен */
				var type	= 1;
				var prize_max	= 0;
				
				for (var key in r.prize ) {
					if (prize_max < r.prize[key])
						prize_max	= r.prize[key];
				}
				
				if (prize_max == 0) {
					type	= 2; // уснули 
				}
				
				var vars	= {
					'vars'	: {
						'prize'	: r.prize,
						'type'	: type
					}
				}
				
				//log('watch end ...');
			}
			
			//log(vars);
			/** если пришел ответ что работа сейчас завершилась надо показать результат */
			SKIN.main(SKIN.parse('fight/fight_watch',vars),SCREEN_WATCH);
		}
		
		/** отменяем текущий поход в дозор */
		t.canselWatch		= function() {
			if (PLAYER.work.getInfo('work_type')!=WORK_TYPE_WATCH) {
				ACTIONS.fight.screenMAin();
				return false;
			}
			
			/** пофигу на ответ - показываем бодалку */
			var def		= function(r) {
				ACTIONS.fight.screenMain();
				return false;
			}
			
			API.call('fight.cancelWatch',{},def,def);
			
		}
			
		/** пробуем атаковать пользователя с enemy_id */
		t.doAttack		= function(enemy_id) {
			/** атака прошла успешно - показываем ход боя */
			var ok		= function(r) {
				ACTIONS.fight.screenLog(r.log_id);
			}
			
			/** не получилось напасть */
			var error	= function(r) {
				bAlert(g('error.fight_'+r.code));
				
				//if (SKIN.nowPopup() == POPUP_FIGHT_SEARCH) {
					/** подсветить кнопку next */
					$('.next_player').addClass('force');
					
				//}
			}
			
			API.call('fight.doAttack',{'enemy_id':enemy_id},ok,error);
		}
		
		t.search		= searchHandler(t);
		function searchHandler(self) {
			var t		= {
				'self'		: self
			}
			
			var _cache	= {
				'data'		: {},			// опции поиска
				'enemy_list'	: {},			// список всех предыдущих показанных людей
				'show_now'	: 0			// индекс показа людей
			}
			
			/** кликнули на кнопку базового поиска противника в бодалке */
			t.standart	= function() {
				_clear();
				_cache.data = {
					'search'	: {
						'base'	: $('#fight_search_select').val()
					},
					'type'		: 'standart'
				}
				
				_find(_cache.show_now);
			}
			
			/** кликнули на кнопку расширенного поиска по уровням */
			t.extra		= function(min, max) {
				_clear();
				_cache.data = {
					'search'	: {
						'min'	: $('#fight_search_level_min').val(),
						'max'	: $('#fight_search_level_max').val()
					},
					'type'	: 'extra'
				}
				
				if (typeof min != 'undefined' && typeof max != 'undefined') {
					_cache.data = {
						'search'	: {
							'min'	: min,
							'max'	: max
						},
						'type'	: 'extra'
					}
				}
				
				_find(_cache.show_now);
			}
			
			/** следюущий соперник */
			t.next	= function(index) {
				_cache.show_now++;
				if (typeof _cache.enemy_list[_cache.show_now]=='undefined') {
					_find(_cache.show_now);
				} else {
					_show(_cache.show_now);
				}
				
				$('.next_player').removeClass('force');
			}
			
			/** предыдущий соперник */
			t.prev	= function(index) {
				_cache.show_now	= limit(_cache.show_now-1,0);
				//log(_cache.show_now);
				_show(_cache.show_now);
			}
			
			t.html	= htmlHandler(t);
			function htmlHandler(self) {
				var t = {
					'self'	: self
				}
				
				
				return;
			}
			
			/** 
			 * -------------------------------------------------- 
			 *			PROTECTED
			 * -------------------------------------------------- 
			 * */
	
			/** посылаем запрос на сервер */
			function _find(index) {
				var ok		= function(r) {
					_cache.enemy_list[index]	= r;
					/** добавляем в USERJS */
					if (typeof r.user!=='undefined' && typeof r.user.user_id!=='undefined')
						USERJS.add(r.user);
					
					_show(index);
				}
				
				var error	= function(r) {
					if (r.code == 10) {
						lAlertNoMoney();
						return ;
					}
					
					bAlert(g('error.fight_'+r.code));
					return ;
				}
				
				API.call('fight.search',_cache.data,ok,error);
			}
			
			/** показыаем окно соперника */
			function _show(index) {
				var data	= _cache.enemy_list[index];
				var vars	= {
					'vars'	: data
				}
								
				/** коректируем данные */
				vars.vars.avatar_url	= getUserAvatarLink(data.user_id,190,'n');
				
				/** формируем проценты */
				var max	= 0;	
				/** находим макс */
				for(var key in data.stats){
					var value = data.stats[key];	//value равен значения, а key = (power, block...)

					for(var key2 in value) {
						var value2 = value[key2]; //value2 равен значениям (50, 10, 40), key2 = active, now, price
						if (key2 == 'now') {								
							if(max < intval(value2)){
								var max = intval(value2);
							}
						}
					}												
				}	

				/** присваиваем проценты */										
				for(var key in data.stats){												
					vars['vars']['stats'][key]['percent'] = ceil(vars['vars']['stats'][key]['now'] / (max / 100));
				}
				
				SKIN.popupShow(SKIN.parse('fight/fight_find_popup',vars),POPUP_FIGHT_SEARCH);
			}
			
			/** очищаем перед новым поиском */
			function _clear() {
				_cache.data		= {};
				_cache.enemy_list	= {};
				_cache.show_now		= 0;
			}
			
			return t;
		}
		
		return t;
	}	

	t.village	= villageHandler(t);
	function villageHandler(self) {
		var t	= {};
		t.self	= self;
		
		/** показываем экран "деревня" */
		t.screenMain		= function() {						
			SKIN.main(SKIN.parse('village/village_main'),SCREEN_VILLAGE);
		}
		
		/** показываем экран "жилище" */
		t.screenHouse		= function(tab_active) {
			tab_active	= tab_active || 2;	// 1 - постройки \ 2 - тотемы
			
			/** показываем экран наверху - с улучшениями */
			var img		= (function(){
				
				function getImageSign(str) {
					return strtoupper(dechex(str));
				}
				
				var order	= ['woodoo1','woodoo2','totem1','totem2'];
				var layers	= [];

				var temp	= '2'+getImageSign(PLAYER.house.getInfo('fence')) + ''+ getImageSign(PLAYER.house.getInfo('road'));
				layers.push(temp);

				var layer1	= '1'+getImageSign(PLAYER.house.getInfo('home')) + ''+ getImageSign(PLAYER.house.getInfo('out'));

				var safe1	= PLAYER.house.have('safe1')	? (PLAYER.house.have('safe3')	? 2 : 1 ) : 0;
				var safe2	= PLAYER.house.have('safe2')	? (PLAYER.house.have('safe4')	? 2 : 1 ) : 0;

				var layer3	= '3'+''+safe1+''+safe2;
				for (var i in order) {
					layer3	+= PLAYER.house.have(order[i]) 	? 1 : 0 ;
				}
		
				layers.push(layer3);

				
				var layers_str	= "";
				for (var i in layers) {
					layers_str	= "<div style=\"background:url('"+IMG_URL+"/images/modules/house/"+layers[i]+".png')\">"+layers_str+"</div>";
				}
				
				var txt		= "<div id='houseDiv' class=\"village_image\" style=\"background:url('"+IMG_URL+"/images/modules/house/"+layer1+".jpg')\">"+layers_str+"</div>";
				return 	txt;
			})();
			
			SKIN.main(SKIN.parse('village/village_house',{'img':img,'tab_active':tab_active}),SCREEN_HOUSE);
		}						
		
		/** показываем экран "лавки" */
		t.screenShop		= function() {						
			var onLoad	= function(response) {
				SKIN.main(SKIN.parse('village/village_shop',{'list':response}),SCREEN_VILLAGE_SHOP);
			}
			
			API.call('shop.getList',{'type':'items','level':PLAYER.profile.getInfo('level')},onLoad);
			
		}						
		
		/** ферма - сама понимает есть ли сейчас работа или нет */
		t.screenFarm		= function() {
			
			/** можно начинать работу */
			var ok		= function(r) {
				var vars	= {
					'vars'	: {
						'farm_desc'	: g('location.farm_work_desc',r),
						'hours'		: r.hours
					},
					'type'	: 0
				}
				SKIN.main(SKIN.parse('village/village_farm',vars),SCREEN_FARM);
			}
			
			/** мы уже - прямо сейчас работаем на ферме */
			var error	= function(r) {
				var vars = {
					'vars'	: {
						'hours' 	: r.hours,
						'till'		: r.till,
						'fine'		: r.fine,
						'desc'		: g('location.farm_desc_'+r.level)
					},
					'type'	: 1
				}
				SKIN.main(SKIN.parse('village/village_farm',vars),SCREEN_FARM);
			}
			
			API.call('profile.getFarmInfo',{},ok,error);
		}
		
		/** начинаем работать на ферме */
		t.doFarm		= function() {
			var th		= this;
			var interval	= $('#farm_select_interval').val();
			if (interval < 1) {
				bAlert({
					'title'	: g('error.farm_error_time_title'),
					'text'	: g('error.farm_error_time')
				});
				return ;
			}
			
			var data	= {
				'interval'	: interval
			}
			
			/** ok */
			var ok		= function(r) {
				th.screenFarm();
				return ;
			}
			
			/** error */
			var error	= function(r) {
				/** уже работаем на ферме  */
				if (r.code == 4) {
					bAlert({
						'title'	: g('error.farm_balert_title'),
						'text'	: g('error.farm_code_4')
					});
					return;
				}
				
				/** работаем где-то еще */
				if (r.code == 5) {
					bAlert({
						'title'	: g('error.farm_balert_title'),
						'text'	: g('error.farm_code_5')
					});
					return;
				}
				
				/** игрок в клановом штурме */
				if (r.code == 6) {
					bAlert({
						'title'	: g('error.farm_balert_title'),
						'text'	: g('error.farm_code_6')
					});
					return;
				}
			}
			
			API.call('profile.doFarm',data,ok,error);
		}
		
		/** отменить работу на ферме */
		t.cancelFarm		= function() {
			var ok	= function() {
				ACTIONS.village.screenFarm();
			}
			
			API.call('profile.cancelFarm',{},ok);
		}
		return t;
	}	
	
	t.shop		= shopHandler();
	function shopHandler(self) {
		var t	= {};
		t.self	= self;
		
		/** кеш */
		var datastore	= {
			'actions'	: {}	// Когда кликаем на кнопку из попапа, отсюда берем действия которые надо совершить
		}
		
		/** показать и обработать окно покупки тотемов */
		t.house	= houseHandler(t);
		function houseHandler(self) {
			var t		= {};
			t.self		= self;
			
			// локальный кеш объектов и параметров 
			var datastore	= {
				'item'	: {},
				'popup'	: {}
			};	
			
			/**
			 * -----------------------------------------------------
			 *			Public 
			 * -----------------------------------------------------
			 **/
			
			/** возращаем из datastore - описание вещи. Используется в SOCIAL.tell.about */
			t.getInfo	= function(id) {
				if (typeof datastore.item[id]!= 'undefined')
					return datastore.item[id];
					
				return false;
			}
			
			/** вызываем popup покупки тотема */
			t.show	= function(id) {
				var onload = function(response) {
					var item	= response[id];
					if (typeof item === 'undefined') {
						alert('Response from shop.getInfo - ERROR');
						return;
					}
					
					/** базовые параметры */
					var popup_param	= {
						//'wiki'		: 'wiki_test_id',
						'id'		: item['id'],
						'title'		: item['title'],
						'img_url'	: IMG_URL + '/images/items/'+item['img'] + '.jpg',
						'desc'		: item['desc'],
						'desc2'		: item['desc2'],
						'price'		: item['price'],
						'until'		: item['extra']['until'],
						'button_yes'	: {
							'title'		: item['extra']['until'] > 0 ? 'Продлить' : 'Активировать',
							'action'	: function() {
								ACTIONS.shop.house.buy(item['id']);
							}
						}		
					}
					
					/** перехватчик когда улучшение в жилище не возможно */
					if (item['id'] == 'fence' || item['id'] == 'road' || item['id'] == 'out' ||item['id'] == 'plant' ||item['id'] == 'home') {
						popup_param.button_yes.title = 'Улучшить';
						if (count(item['price'])==0) {
							popup_param.button_yes		= {};
							popup_param.replace_button_text	= "<div class='replace_button_text'>Дальнейшее улучшение невозможно.</div>";
						}
					}
					
					
					/** корректируем если надо расширеннные */
					if (typeof item['img_url'] !=='undefined') {
						popup_param['img_url']	= item['img_url'];
					}
					
					/** заносим в локальный кеш */
					datastore.item[item['id']]	= item;
					datastore.popup[item['id']]	= popup_param;
					
					/** формируем блоки html*/
					var html	= p_makePopup(popup_param);
					
					/** выводим */
					SKIN.popupShow(html);
				}
				
				API.call('shop.getInfo',{'type':'house','id':id},onload);
			}
			
			/** пробуем купить house  */
			t.buy	= function(id) {
				var data = {
					'price_type'	: this.self.getSelectedPriceType(),
					'id'		: id,
					'type'		: 'house'
				}
				
				var th	= this;
				API.call('shop.buy',data,function(r){th.okHandler(r);},function(r){th.errorHandler(r)});
			}
			
			/** обработчик ошибок при покупке */
			t.errorHandler	= function(response) {
				if (response.code == ERROR_CODE_NO_MONEY) {
					lAlertNoMoney();
				} else if (intval(response.code) < 10){
					lAlertGlobalError(response.message);
				} else {
					lAlert(g('error.shop_'+response.code));
				}
			}
			
			/** обработчик если покупка прошла успешно */
			t.okHandler	= function(response) {
				bOk(g('global.upgrade_complete'));
				SKIN.popupClose();
				
				/** определяем какой экран показать */
				var screen_num	= 2;
				if (response.id == 'home' || response.id == 'out' || response.id == 'plant' || response.id == 'fence' || response.id == 'road')
					screen_num	= 1;
				
				if (SKIN.nowScreen() == SCREEN_HOUSE)
					ACTIONS.village.screenHouse(screen_num);
				else if (SKIN.nowScreen() == SCREEN_PROFILE) 
					SKIN.profile.reloadHouse();
			}
			
			/**
			 * -----------------------------------------------------
			 *		Private - c префикос p_
			 * -----------------------------------------------------
			 **/
			
			
			/** формируем тело popup для покупки */
			function p_makePopup(conf) {
				var info = {
					'wiki'	: conf.wiki || '',
					'title'	: conf.title || '',
					'content' : ''	// будет заполнен ниже 
				};
				
				/** генерируем блок с ценой */
				conf.price_block = t.self.html.popupPriceBlock(conf);
				
				/** заполняем контент */
				info.content	= p_popupTotemBody(conf);
				
				/** формируем обертку */
				var txt	= t.self.html.popupMain(info);
				return txt;
			}
			
			/** Для тотемов - с ленточкой действует еще | Картинка img_url \ Описание desc \ Описание снизу desc2 \ Блок цены и кнопка price_block */
			function p_popupTotemBody(info) {
				var until	= '';
				
				/** значения по умолчанию */
				info.until		= info.until || 0;
				info.img_url		= info.img_url || '';
				info.desc		= info.desc || '';
				info.desc2		= info.desc2 || '';
				info.price_block	= info.price_block || '';
				
				
				/** если указано действует */
				if (info.until > 0) {
					var id	= 'timer_' + getRandId();
					until	= '<div class="buy_tooltip"><div></div><div class="white center p02">Действует еще:<br /><b class="yellow"><span id="{ID}" class="day_on"></span><script>timer({"id":"#{ID}","time":"{UNTIL}"});</script></b></div><div></div></div>'.format({'ID':id,'UNTIL':info.until});
				}
				
				var desc2	= '';
				if (info.desc2 !== '') {
					desc2	= '<div class="popup_desc pl10 pt10">'+info.desc2+'</div>';
				}
				
				
				var txt		= '\n\
				<!--функциональная часть окна-->\n\
						<div class="pt8 clear">\n\
							<div class="clear_fix">\n\
								<div class="purchase fl_l ml10 w180" style="background: url(/*можно вставить картинку сюда*/) no-repeat;">\n\
									<img src="'+info.img_url+'" alt="" />\n\
									'+until+'\n\
								</div>\n\
								<div class="fl_r w315 popup_desc">\n\
									'+info.desc+'\n\
								</div>\n\
							</div>\n\
							'+desc2+'\n\
							<div>'+info.price_block+'</div>\n\
						</div>\n\
				';
				return  txt;
			}
			
			return t;
		}
		
		/** показать и обработать окно покупки вещей в лавке */
		t.items		= itemsHandler(t);
		function itemsHandler(self) {
			var t		= {};
			t.self		= self;
			t.afterBuy	= function(){};
			// локальный кеш объектов и параметров 
			var datastore	= {
				'item'	: {},
				'popup'	: {}
			};	
			/**
			 * -----------------------------------------------------
			 *			Public 
			 * -----------------------------------------------------
			 **/
			
			/** возращаем из datastore - описание вещи. Используется в SOCIAL.tell.about */
			t.getInfo	= function(id) {
				if (typeof datastore.item[id]!= 'undefined')
					return datastore.item[id];
					
				return false;
			}
			
			/** вызываем popup покупки тотема */
			t.show	= function(id,conf) {
				conf	= conf || {};
				conf.afterBuy	= conf.afterBuy || function() {};
				
				/** действие после покупки предмета */
				this.afterBuy	= conf.afterBuy;
				
				/** обертка */
				var onload = function(response) {
					var item	= response['item_'+id];
					if (typeof item === 'undefined') {
						alert('Response from shop.getInfo - ERROR');
						return;
					}
					
					/** базовые параметры */
					var popup_param	= {
						'wiki'		: '',
						'id'		: item['id'],
						'title'		: item['title'],
						'img_url'	: IMG_URL + '/images/items/'+item['img'] + '.jpg',
						'desc'		: item['desc'],
						'desc2'		: item['desc2'],
						'price'		: item['price'],
						'button_yes'	: {
							'title'		: 'Купить',
							'action'	: function() {
								ACTIONS.shop.items.buy(item['id']);
							}
						}
							
					}
					
					/** корректируем если надо расширеннные */
					if (typeof item['img_url'] !=='undefined') {
						popup_param['img_url']	= item['img_url'];
					}
					
					/** заносим в локальный кеш */
					datastore.item[item['id']]	= item;
					datastore.popup[item['id']]	= popup_param;
					
					/** формируем блоки html*/
					var html	= p_makePopup(popup_param);
					
					/** выводим */
					SKIN.popupShow(html);
				}
				
				API.call('shop.getInfo',{'type':'items','id':id},onload);
			}
			
			/** пробуем купить Item  */
			t.buy	= function(id,price_type) {
				var data = {
					'price_type'	: typeof price_type == 'undefined' ? this.self.getSelectedPriceType() : price_type,
					'id'		: id,
					'type'		: 'items'
				}
				
				var th	= this;
				API.call('shop.buy',data,function(data){th.okHandler(data)},function(data){th.errorHandler(data)});
			}
			
			/** обработчик ошибок при покупке */
			t.errorHandler	= function(response) {
				if (response.code == ERROR_CODE_NO_MONEY) {
					lAlertNoMoney();
				} else if (intval(response.code) < 10){
					lAlertGlobalError(response.message);
				} else {
					bAlert(g('error.shop_'+response.code));
				}
			}
			
			/** обработчик если покупка прошла успешно */
			t.okHandler	= function(response) {
				SKIN.popupClose();
				bOk(g('global.buy_ok'));
				this.afterBuy();
			}
			
			
			/**
			 * -----------------------------------------------------
			 *		Private - c префикос p_
			 * -----------------------------------------------------
			 **/
			
			
			/** формируем тело popup для покупки */
			function p_makePopup(conf) {
				var info = {
					'wiki'	: conf.wiki || '',
					'title'	: conf.title || '',
					'content' : ''	// будет заполнен ниже 
				};
				
				/** генерируем блок с ценой */
				conf.price_block = t.self.html.popupPriceBlock(conf);
				
				/** заполняем контент */
				info.content	= t.self.html.popupStandartBody(conf);
				
				/** формируем обертку */
				var txt	= t.self.html.popupMain(info);
				return txt;
			}
			
			/** Для тотемов - с ленточкой действует еще | Картинка img_url \ Описание desc \ Описание снизу desc2 \ Блок цены и кнопка price_block */
			function p_popupTotemBody(info) {
				var until	= '';
				
				/** значения по умолчанию */
				info.until		= info.until || 0;
				info.img_url		= info.img_url || '';
				info.desc		= info.desc || '';
				info.desc2		= info.desc2 || '';
				info.price_block	= info.price_block || '';
				
				
				/** если указано действует */
				if (info.until > 0) {
					until	= '<div class="buy_tooltip"><div></div><div class="white center p02">Действует до:<br /><b class="yellow">00:15 15.12.2011</b></div><div></div></div>';
				}
				
				var desc2	= '';
				if (info.desc2 !== '') {
					desc2	= '<div class="popup_desc pl10 pt10">'+info.desc2+'</div>';
				}
				
				
				var txt		= '\n\
				<!--функциональная часть окна-->\n\
						<div class="pt8 clear">\n\
							<div class="clear_fix">\n\
								<div class="purchase fl_l ml10 w180" style="background: url(/*можно вставить картинку сюда*/) no-repeat;">\n\
									<img src="'+info.img_url+'" alt="" />\n\
									'+until+'\n\
								</div>\n\
								<div class="fl_r w320 popup_desc">\n\
									'+info.desc+'\n\
								</div>\n\
							</div>\n\
							'+desc2+'\n\
							<div>'+info.price_block+'</div>\n\
						</div>\n\
				';
				return  txt;
			}
			
			return t;
		}
		
		/** показать и обработать окно улучшений в клане */
		t.clan	= clanHandler(t);
		function clanHandler(self) {
			var t		= {};
			t.self		= self;
			
			// локальный кеш объектов и параметров 
			var datastore	= {
				'item'	: {},
				'popup'	: {}
			};	
			
			/**
			 * -----------------------------------------------------
			 *			Public 
			 * -----------------------------------------------------
			 **/
			
			/** возращаем из datastore - описание вещи. Используется в SOCIAL.tell.about */
			t.getInfo	= function(id) {
				if (typeof datastore.item[id]!= 'undefined')
					return datastore.item[id];
					
				return false;
			}
			
			/** вызываем popup покупки */
			t.show	= function(id) {
				var onload = function(response) {
					var item	= response[id];
					if (typeof item === 'undefined') {
						alert('Response from shop.getInfo - ERROR');
						return;
					}
					
					/** базовые параметры */
					var popup_param	= {
						//'wiki'		: 'wiki_test_id',
						'id'		: item['id'],
						'title'		: item['title'],
						'img_url'	: item['img_url'],
						'desc'		: item['desc'],
						'desc2'		: item['desc2'],
						'price'		: item['price'],
						'button_yes'	: {
							'title'		: 'Улучшить',
							'action'	: function() {
								ACTIONS.shop.clan.buy(item['id']);
							}
						}		
					}
					
					popup_param.button_yes.title = 'Улучшить';
					if (count(item['price'])==0) {
						popup_param.button_yes		= {};
						popup_param.replace_button_text	= "<div class='replace_button_text'>Дальнейшее улучшение невозможно.</div>";
					}
					
					/** заносим в локальный кеш */
					datastore.item[item['id']]	= item;
					datastore.popup[item['id']]	= popup_param;
					
					/** формируем блоки html*/
					var html	= p_makePopup(popup_param);
					
					/** выводим */
					SKIN.popupShow(html);
				}
				
				API.call('shop.getInfo',{'type':'clan','id':id},onload);
			}
			
			/** пробуем купить house  */
			t.buy	= function(id) {
				var data = {
					'price_type'	: this.self.getSelectedPriceType(),
					'id'		: id,
					'type'		: 'clan'
				}
				
				var th	= this;
				API.call('shop.buy',data,function(r){th.okHandler(r);},function(r){th.errorHandler(r)});
			}
			
			/** обработчик ошибок при покупке */
			t.errorHandler	= function(response) {
				if (response.code == ERROR_CODE_NO_MONEY) {
					lAlertNoMoney();
				} else if (intval(response.code) < 10){
					lAlertGlobalError(response.message);
				} else {
					lAlert(g('error.shop_'+response.code));
				}
			}
			
			/** обработчик если покупка прошла успешно */
			t.okHandler	= function(response) {
				SKIN.popupClose();
				ACTIONS.clan.screenMain();
				bOk(g('clan.upgrade_ok'));
			}
			
			/**
			 * -----------------------------------------------------
			 *		Private - c префикос p_
			 * -----------------------------------------------------
			 **/
			
			
			/** формируем тело popup для покупки */
			function p_makePopup(conf) {
				var info = {
					'wiki'	: conf.wiki || '',
					'title'	: conf.title || '',
					'content' : ''	// будет заполнен ниже 
				};
				
				/** генерируем блок с ценой */
				conf.price_block = t.self.html.popupPriceBlock(conf);
				
				/** заполняем контент */
				info.content	= t.self.html.popupStandartBody(conf);
				
				/** формируем обертку */
				var txt	= t.self.html.popupMain(info);
				return txt;
			}
			
			return t;
		}
		
		/** показать и обработать окно покупки зверушки */
		t.pet	= petHandler(t);
		function petHandler(self) {
			var t		= {};
			t.self		= self;
			
			// локальный кеш объектов и параметров 
			var datastore	= {
				'item'	: {},
				'popup'	: {}
			};	
			
			/**
			 * -----------------------------------------------------
			 *			Public 
			 * -----------------------------------------------------
			 **/
			
			/** возращаем из datastore - описание вещи. Используется в SOCIAL.tell.about */
			t.getInfo	= function(id) {
				if (typeof datastore.item[id]!= 'undefined')
					return datastore.item[id];
					
				return false;
			}
			
			/** вызываем popup покупки */
			t.show	= function(id) {
				var onload = function(response) {
					var item	= response[0];
					
					
					/** базовые параметры */
					var popup_param	= {
						//'wiki'		: 'wiki_test_id',
						'id'		: item['id'],
						'title'		: item['title'],
						'img_url'	: item['img_url'],
						'desc'		: item['desc'],
						'desc2'		: item['desc2'],
						'price'		: item['price'],
						'button_yes'	: {
							'title'		: 'Купить',
							'action'	: function() {
								ACTIONS.shop.pet.buy(item['id']);
							}
						}		
					}
					
					popup_param.button_yes.title = 'Купить';
					if (count(item['price'])==0) {
						popup_param.button_yes		= {};
						popup_param.replace_button_text	= "<div class='replace_button_text'>Дальнейшее улучшение невозможно.</div>";
					}
					
					/** заносим в локальный кеш */
					datastore.item[item['id']]	= item;
					datastore.popup[item['id']]	= popup_param;
					
					/** формируем блоки html*/
					var html	= p_makePopup(popup_param);
					
					/** выводим */
					SKIN.popupShow(html);
				}
				
				API.call('shop.getInfo',{'type':'pet','id':id},onload);
			}
			
			/** пробуем купить house  */
			t.buy	= function(id) {
				var data = {
					'price_type'	: this.self.getSelectedPriceType(),
					'id'		: id,
					'type'		: 'pet'
				}
				
				var th	= this;
				API.call('shop.buy',data,function(r){th.okHandler(r);},function(r){th.errorHandler(r)});
			}
			
			/** обработчик ошибок при покупке */
			t.errorHandler	= function(response) {
				if (response.code == ERROR_CODE_NO_MONEY) {
					noMoney();
				} else if (intval(response.code) < 10){
					lAlertGlobalError(response.message);
				} else {
					bAlert(g('error.shop_'+response.code));
				}
			}
			
			/** обработчик если покупка прошла успешно */
			t.okHandler	= function(response) {
				bOk(g('location.pet_buy_ok'));
				
				SKIN.popupClose();
				ACTIONS.pet.screenMain();
			}
			
			/**
			 * -----------------------------------------------------
			 *		Private - c префикос p_
			 * -----------------------------------------------------
			 **/
			
			
			/** формируем тело popup для покупки */
			function p_makePopup(conf) {
				var info = {
					'wiki'	: conf.wiki || '',
					'title'	: conf.title || '',
					'content' : ''	// будет заполнен ниже 
				};
				
				/** генерируем блок с ценой */
				conf.price_block = t.self.html.popupPriceBlock(conf);
				
				/** заполняем контент */
				info.content	= t.self.html.popupStandartBody(conf);
				
				/** формируем обертку */
				var txt	= t.self.html.popupMain(info);
				return txt;
			}
			
			return t;
		}
		
		/** храним основные html шаблоны */
		t.html			= htmlHander(t);
		function htmlHander(self) {
			var t	= {};
			t.self	= self;
			
			/** формируем нижний блок цен - с кнопкой купить */
			t.popupPriceBlock	= function(info) {
				var action_id		= 'm_' + time();
				datastore.actions[action_id]	= info.button_yes.action;
				
				
				
//				/**
//				 * info.price - представляет из себя объект вида: {
//				 *	type1 : {
//				 *		'money1':100,
//				 *		'sp_slaves': 15
//				 *	},
//				 *	type2 : {
//				 *		'money3':10,
//				 *		'money10': 150
//				 *	}
//				 * }
//				 * 
//				 * Данный пример илюстрирует покупку либо за золото и работв, либо за зелень и пирашки
//				 * */
//				var money_list	= [];
//				var money_txt	= '';
//				if (count(info.price)> 1) {
//					for (var type in info.price) {
//						var checked	= '';
//						var icon_block	= ''; 
//						for (var money_ico in info.price[type]) {
//							icon_block	+= info.price[type][money_ico] + ' ' + g('icon.'+money_ico);
//
//							/** активация валюты по умолчанию */
//							if (money_ico == 'money1' || money_ico == "money2")
//								checked = 'checked';
//						}
//
//						var money_block	= '<input type="radio" name="price_type" value="'+type+'" '+checked+'>'+icon_block;
//						money_list.push(money_block);
//					}
//					
//					money_txt	= money_list.join('&nbsp;\\&nbsp;');
//				} else {
//					for (var type in info.price) {
//						var icon_block	= ''; 
//						for (var money_ico in info.price[type]) {
//							if (info.price[type][money_ico] == 0) {
//								icon_block	+= '<div class="mt10 mb7">Первая покупка - <span class="bold">бесплатно</span></div>';
//							} else {
//								icon_block	+= 'Цена покупки: ' + digit(info.price[type][money_ico]) + ' ' + g('icon.'+money_ico);
//							}
//						}
//
//						var money_block	= '<input type="hidden" name="price_type" value="'+type+'" >'+icon_block;
//						money_list.push(money_block);
//						money_txt	= money_list.join('&nbsp;\\&nbsp;');
//					}
//					
//					money_txt	= money_list.join('');
//				}
				
				var money_txt	= SKIN.price.getBlock(info.price);
				
				/** если передан параметр замены блока покупки на сообщение - info.replace_button_text */
				if (typeof info.replace_button_text !=='undefined' && info.replace_button_text !=='') {
					var txt	= '\n\
					<div class="buy_bottom_area clear clear_fix ">'+info.replace_button_text+'</div>';
				} else {
					var txt	= '\n\
					<div class="buy_bottom_area clear clear_fix ">\n\
						<div class="mt7 center black">\n\
							'+money_txt+'\n\
						</div>\n\
						<div class="buy_buttons" >\n\
							<div class="button" id="tutorial_button_popup_buy" onclick="TUTORIAL.click(this); GLOBAL.setObj(this,-150); ACTIONS.shop.buttonClick(\''+action_id+'\') "><span>'+info.button_yes.title+'</span></div>\n\
						</div>\n\
					</div>';
				}
				return txt;
			}
			
			/** формируем стандартный блок выбора цены и возвращает html */
			t.priceBlock		= function(price) {
				return SKIN.price.getBlock(price);
			}
			
			/** стандартное тело popup | Картинка img_url \ Описание desc \ Описание снизу desc2 \ Блок цены и кнопка price_block */
			t.popupStandartBody	= function(info) {
				/** значения по умолчанию */
				info.img_url		= info.img_url || '';
				info.desc		= info.desc || '';
				info.desc2		= info.desc2 || '';
				info.price_block	= info.price_block || '';
				

				var desc2	= '';
				if (info.desc2 !== '') {
					desc2	= '<div class="static_block mt8 ml8 mr8">\n\
						<div class="block_title slide_block center bold pointer {SHOWN}" onclick="SKIN.toggleShown(23,this)"><div class="title_icon"></div>{DETAILS}</div>\n\
						<div class="block_content lh150 p10 shown_23">{DESC}</div>\n\
					</div>'.format({'SHOWN' : SKIN.openIfShown(23), 'DETAILS' : g('location.details'),'DESC':info.desc2});
				}
				
				
				var txt		= '\n\
				<!--функциональная часть окна-->\n\
						<div class="pt8 clear">\n\
							<div class="clear_fix">\n\
								<div class="purchase fl_l ml10 w180" style="background: url(/*можно вставить картинку сюда*/) no-repeat;">\n\
									<img src="'+info.img_url+'" alt="" />\n\
								</div>\n\
								<div class="fl_r w315 popup_desc">\n\
									'+info.desc+'\n\
								</div>\n\
							</div>\n\
							'+desc2+'\n\
							<div>'+info.price_block+'</div>\n\
						</div>\n\
						<script>\n\
							SKIN.initShown(23,1);\n\
						</script>\n\
				';
				return  txt;
			}

			/** обертка для popup */
			t.popupMain	= function(info) {
				info.wiki	= info.wiki || '';
				info.content	= info.content || '';
				info.title	= info.title || 'Сообщение';
				
				var wiki	= '';
				if (info.wiki!='') {
					wiki	= '<span href="" class="pointer wiki" onclick="ACTIONS.showWiki(\''+info.wiki+'\');">' + g('icon.wiki') + '</span>';
				}
				
				
				var txt = '\n\
				<div class="center_buy" id="buy">\n\
					<div class="popup">\n\
						'+ wiki +'\n\
						<div class="popup_title"><span class="mt18">'+ info.title +'</span></div><span class="close" onclick="BTN.closePopup();"></span><div class="upload hidden"></div>\n\
					</div>\n\
					<div>\n\
						'+ info.content +'\n\
					</div>\n\
					<div></div>\n\
				</div>\n\
				';

				return txt;
			}
			
			return t;
		}
		
		/** функция обработчик всех кнопок купить \ продлить \ активировать в */
		t.buttonClick	= function(id) {
			/** Общая идея такая:*/
			datastore.actions[id]();
		}
		
		/** возращает выбранный price_type */
		t.getSelectedPriceType	= function() {
			return SKIN.price.getSelected();
		}
		
		return t;
	}
	
	t.mail		= mailHandler(t);
	function mailHandler(self) {
		var t		= {};
		t.self		= self;
		t.group		= 3;	// по умолчанию приключения
		t.path		= {
			'tab_main'	: '#message_main',
			'tab_user'	: '#message_user',
			'tab_clan'	: '#message_clan'
		}
		
		
		
		/** главный экран почты вместе со вкладками */
		t.main		= mainHandler(t);
		function mainHandler(self) {
			var t		= {};
			t.self		= self;
			
			t.path	= {
				'list'		: '#message_main .list',
				'more'		: '#message_main .read_more',
				'btn'		: '#messages_change_type_tabs .btn',
				'group1'	: '#counter_group1',
				'group2'	: '#counter_group2',
				'group3'	: '#counter_group3',
				'group19'	: '#counter_group19',
				'group20'	: '#counter_group20'			
			}
			t.counters	= {};
			
			var _page		= 1;
			var _message_list	= {};	// здесь храним список сообщений. Обнуляем каждый раз при показе новой группы или окна целиком

			/** меняем вкладку */
			t.group			= function(new_group) {
				$(this.path.btn).removeClass('selected');
				$(this.path.btn+'[name='+new_group+']').addClass('selected');

				this.self.group		= new_group;
				
				/** если клан - то сразу показываем окно какбы переписки */
				if (new_group == 2) {
					ACTIONS.mail.clanCorrespondence.show();
					return ;
				}
							
				_setDefault();
				_load();
			}

			/** показываем главный экран */
			t.show			= function() {
				_setDefault();
				SKIN.main(SKIN.parse('mail/mail_main',{'show_screen':0}),SCREEN_MAIL);
				this.group(this.self.group);			
			}	

			/** при наводе на блок сообщения */
			t.hover			= function(obj) {
				var parent	= $(obj).parent();
				if ($(parent).hasClass('new')) {
					$(parent).removeClass('new');

					var group	= 'group' + this.self.group;
					if (this.counters[group] > 0) {
						this.counters[group]--;
						_updateCounters(group);
					}
				}
			}						

			/** кликнули показать еще */
			t.more			= function() {			
				_page++;
				_load();
			}

			/** удалить сообщение */
			t.del			= function(id) {												
				var data	= {
					'id'		: id,
					'group_id'	: this.self.group
				};
				
				var ok		= function(r) {
					_deleteMessage(id);
				}
				
				var error	= function(r) {
					bAlert({
						'title'	: g('error.post_balert_error_title'),
						'text'	: g('error.post_delete_some')
					});
				}
				
				/** если это переписка между пользователями и хотим удалить всю переписку, сначала спрашивайте */
				if (this.self.group == 1) {
					lConfirm({
						'width'		: '400',
						'message'	: g('location.post_user_delete_all'),
						'action'	: function() {
							API.call('post.delete',data,ok,error);
						}	
					});
				} else {
					API.call('post.delete',data,ok,error);
				}
				
				
			}

			/** все шаблоны */
			t.html			= htmlHandler(t);
			function htmlHandler(self) {
				var t	= {};
				t.self	= self;

				t.standartBlock		= function(id) {
					var info	= _message_list[id];
					var avatar_url	= '';
					var avatar_html	= '';

					if (typeof info.avatar_url !== 'undefined') 
						avatar_url	= info.avatar_url;
					else
						avatar_url	= IMG_URL + '/avatars/i' + info.avatar + '.jpg';

					avatar_html	= '<img src="'+avatar_url+'" alt="" />';
					
					/** если это аватар живого пользователя - заменяем его на ссылку */
					if (typeof info.user!=='undefined' && typeof info.user.user_id!=='undefined') {
						if (typeof info.avatar_social == 'undefined')
							avatar_html	= getUserAvatarLink(info.user.user_id,50,'i');
						else 
							avatar_html	= '<img src="{AVATAR_URL}" alt="" class="pointer" onclick="ACTIONS.showProfile(\'{USER_ID}\')" />'.format({'AVATAR_URL':info.avatar_social,'USER_ID':info.user_id});
					}
				
					var replace	= {
						'cls'		: info.readed == 0 ? 'new' : '',
						'id'		: info.id,
						'avatar_html'	: avatar_html,
						'title'		: info.title,
						'text'		: info.text,
						'last_update'	: till(info.last_update),
						'title1'	: g('global.delete')
					};
					
					var txt	= '\n\
					<div class="message clear_fix {cls}" id="message_{id}" rel="{id}">\n\
						<div class="message_checkbox hidden fl_l" onclick="ACTIONS.mail.main.click(this)"></div>\n\
						<div class="message_inside pt10 pl10 pr10 pb8" onmouseover="ACTIONS.mail.main.hover(this);">\n\
							<div class="fl_l mr10">{avatar_html}</div>\n\
							<div class="message_data fl_l">\n\
								<div class="message_title">{title}</div>\n\
								<div class="message_description">{text}</div>\n\
								<div class="message_till">{last_update}</div>\n\
							</div>\n\
							<div class="post_close" title="{title1}" onclick="ACTIONS.mail.main.del(\'{id}\');"></div>\n\
						</div>\n\
					</div>';
					return txt.format(replace);

				}

				/** используется для отображения сообщений - при переписке между пользователями */
				t.previewBlock		= function(id) {
					var info	= _message_list[id];
					var avatar_url	= '';

					if (typeof info.avatar_url !== 'undefined') 
						avatar_url	= info.avatar_url;
					else
						avatar_url	= IMG_URL + '/avatars/i' + info.avatar + '.jpg';

					var avatar_html	= '<img src="'+avatar_url+'" alt="" />';
					
					/** если это аватар живого пользователя - заменяем его на ссылку */
					if (typeof info.user!=='undefined' && typeof info.user.user_id!=='undefined') {
						avatar_html	= getUserAvatarLink(info.user.user_id,50,'i');
					}

					var replace	= {
						'cls'		: info.readed == 0 ? 'new' : '',
						'id'		: info.id,
						'avatar_html'	: avatar_html,
						'title'		: info.title,
						'text'		: info.text,
						'last_update'	: till(info.last_update),
						'user_id'	: info.user.user_id,
						'title1'	: g('global.delete')
					};

					var txt	= '\n\
					<div class="message clear_fix {cls}" id="message_{id}" rel="{id}">\n\
						<div class="message_checkbox hidden fl_l" onclick="ACTIONS.mail.main.click(this)"></div>\n\
						<div class="message_inside pt10 pl10 pr10 pb8" onmouseover="ACTIONS.mail.main.hover(this);">\n\
							<div class="fl_l mr10">{avatar_html}</div>\n\
							<div class="message_data fl_l">\n\
								<div class="message_title">{title}</div>\n\
								<div class="message_description">{text}</div>\n\
								<div class="message_till">{last_update}</div>\n\
							</div>\n\
							<div class="post_close" title="{title1}" onclick="ACTIONS.mail.main.del(\'{id}\');"></div>\n\
							<div class="preview_more" onclick="ACTIONS.mail.userCorrespondence.show(\'{user_id}\')"><div></div></div>\n\
						</div>\n\
					</div>';
					return txt.format(replace);

				}

				return t;
			}
			/**
			 * -------------------------------------------------------------
			 *			PROTECTED
			 * -------------------------------------------------------------
			 **/
			
			/** удаляет выбранные сообщения */
			function _deleteMessage(id) {
				_message_list[id] = false;
				$('#message_'+id).animate({'height':0},200,function(){$(this).remove();autoSize();});
			}

			/** единственная точка добавления сообщений */
			function _addMessage(id,data) {
				/** если есть описание пользователя - добавляем его в USERJS */
				if (typeof data.user !== 'undefined' && typeof data.user.user_id !== 'undefined')
					USERJS.add(data.user);
				
				_message_list[id] = data;
				_appendMessage(id);
			}
			
			/** когда открываем новую вкладку - сбрасываем все установки */
			function _setDefault() {
				t.self.showTab('main');
				_message_list	= {};
				$(t.path.list).html('');
				_page		= 1;
				autoSize();
			}
			
			/** грузим сообщения с сервера */
			function _load() {
				var th		= t;	
				var data	= {
					'group'		: t.self.group,
					'page'		: _page
				};

				var ok		= function(r) {	
					if (count(r.messages) == 0) {
						var txt = '<div class="empty">' + g('location.post_empty_list') + '</div>';
						$(th.path.list).html(txt);
						autoSize();
					}else {
						/** добавляем полученные сообщения в локальную базу и там же показываем */
						for (var i in r.messages) {
							_addMessage(i,r.messages[i]);
						}
					}

					/** получаем и показываем счетчики */
					th.counters	= r.counters;
					for (var i in th.counters) {
						/** i = тип счетчика r.counters[i] = значение*/
						_updateCounters(i);
					}


					/** смотрим сколько страниц, показываем \ скрываем блок "показать еще" */
					if (r.params.pages > _page) {
						$(th.path.more).removeClass('hidden');
						autoSize();
					} else {
						$(th.path.more).addClass('hidden');
						autoSize();
					}
					
					TUTORIAL.checkWait();
				}

				var error	= function(r) {
					if (r.code == 5) {
						var txt = 'нету клана';
						$(th.path.list).html(txt);
						autoSize();
					}
				}

				API.call('post.get',data,ok,error);
			}
				
			/** Добавляем сообещние на страницу - все сообщения пржде чем показаться попадают сюда */
			function _appendMessage(id) {
				var txt		= '';

				switch (t.self.group) {
					case 1 :
						/** шабон переписки между пользователямм */
						txt	= t.html.previewBlock(id);
					break;

					default :
						txt	= t.html.standartBlock(id);
					break;
				}

				$(t.path.list).append(txt);
				autoSize();
			}
			
			function _updateCounters(key) {
				var txt = '(<span class="bold">'+t.counters[key]+'</span>)';

				if (t.counters[key] == 0) {
					var txt = '';
				}
				$(t.path[key]).html(txt);
			}
			
			return t;
		}
		
		/** Обработчик переписки между двумя людьми */
		t.userCorrespondence	= ucHandler(t);
		function ucHandler(self) {
			var t	= {};
			t.self		= self;
			t.user_id	= '';
			t.user_data	= {};
			t.path		= {
				'ava_1'		: '#message_user .ava_1',
				'ava_2'		: '#message_user .ava_2',
				'list'		: '#message_user .list',
				'more'		: '#message_user .read_more',
				'area'		: '#message_user_area',
				'empty'		: '#message_user .empty'
			};
			
			/** показываем экран переписки между двумя людьми */
			t.show	= function(user_id) {
				var data	= USERJS.get(user_id);
				if (data === false)
					return ;
				
				if (SKIN.nowScreen() != SCREEN_MAIL)
					SKIN.main(SKIN.parse('mail/mail_main',{'show_screen':1}),SCREEN_MAIL);
				
				this.user_id	= user_id;
				this.user_data	= data;
				
				_prepareScreen();
				_load();
			}
			
			/** обновить список сообщений */
			t.refresh	= function() {
				_prepareScreen();
				_load();
			}
			
			/** вернуться назад */
			t.back		= function() {
				t.self.showTab('main');
			}
			
			/** кликнули показать еще */
			t.more			= function() {			
				_page++;
				_load();
			}
			
			/** отправить сообщение */
			t.send		= function() {
				var txt		= $(this.path.area).val();

				if (txt == '')
					return false;

				var data	= {
					'message'	:txt,
					'to_user'	:this.user_id
				};

				/** отправляем сообщение на сервер */
				API.call('post.send',data,function(r){
					_addMessage(r.id,{
						'author_id'	: PLAYER.user_id,
						'text'		: nl2br(txt),
						'id'		: r.id
					},'prepend');
					$(t.path.area).val('');
				},function(r){
					/** сообщение об ошибке */
					bAlert({
						'time'		: 3000,
						'title'		: g('error.post_balert_error_title'),
						'text'		: g('error.post_send_'+r.code)
					});
				});
			}
			
			/** удалить сообщение */
			t.del			= function(id) {												
				var data	= {
					'id'		: id,
					'user_id'	: this.user_id
				};
				
				API.call('post.deleteUser',data,function(r){
					_deleteMessage(id);
				},function(r){
					bAlert({
						'title'	: g('error.post_balert_error_title'),
						'text'	: g('error.post_delete_some')
					});
				})
			}
			
			/** все шаблоны */
			t.html			= htmlHandler(t);
			function htmlHandler(self) {
				var t	= {};
				t.self	= self;

				t.standartBlock		= function(id) {
					var info	= _message_list[id];
					var avatar_html	= getUserAvatarLink(info['author_id'],50,'i');
					var title	= g('location.post_user_title',{'from':getUserLink(info.author_id)});
				
					var replace	= {
						'id'		: info.id,
						'avatar_html'	: avatar_html,
						'title'		: title,
						'text'		: info.text,
						'last_update'	: till(info.id),
						'title1'	: g('global.delete'),
						'cls'		: info.author_id == PLAYER.user_id ? '' : 'log_bgr1'
					};
					
					var txt	= '\n\
					<div class="message clear_fix {cls}" id="message_{id}" rel="{id}">\n\
						<div class="message_checkbox hidden fl_l"></div>\n\
						<div class="message_inside pt10 pl10 pr10 pb8">\n\
							<div class="fl_l mr10">{avatar_html}</div>\n\
							<div class="message_data fl_l">\n\
								<div class="message_title">{title}</div>\n\
								<div class="message_description">{text}</div>\n\
								<div class="message_till">{last_update}</div>\n\
							</div>\n\
							<div class="post_close" title="{title1}" onclick="ACTIONS.mail.userCorrespondence.del(\'{id}\');"></div>\n\
						</div>\n\
					</div>';
					return txt.format(replace);
				}
				
				return t;
			}
			
			/**
			 * -----------------------------------------------------
			 *			PROTECTED
			 * -----------------------------------------------------
			 **/
			
			var _message_list	= {};	// список сообщений между пользователями 
			var _page		= 1;
			
			/** удаляет выбранные сообщения */
			function _deleteMessage(id) {
				_message_list[id] = false;
				$('#message_'+id).animate({'height':0},200,function(){$(this).remove();autoSize();});
			}

			/** единственная точка добавления сообщений */
			function _addMessage(id,data,mode) {
				$(t.path.empty).addClass('hidden');
				mode	= mode || 'append';
				_message_list[id] = data;
				
				if (mode ==='prepend') {
					_prependMessage(id);
				} else {
					_appendMessage(id);
				}
			}
			
			/** грузим сообщения с сервера */
			function _load() {
				var th		= t;	
				var data	= {
					'user_id2'	: t.user_id,
					'page'		: _page
				};

				var ok		= function(r) {	
					if (count(r.messages) == 0) {
						var txt = '<div class="empty">' + g('location.post_empty_list') + '</div>';
						$(th.path.list).html(txt);
					} else {
						/** добавляем полученные сообщения в локальную базу и там же показываем */
						for (var i in r.messages) {
							_addMessage(i,r.messages[i]);
						}
					}

					/** смотрим сколько страниц, показываем \ скрываем блок "показать еще" */
					if (r.params.pages > _page) {
						$(th.path.more).removeClass('hidden');
					} else {
						$(th.path.more).addClass('hidden');
					}
					
					autoSize();
				}

				var error	= function(r) {
					if (r.code == 5) {
						var txt = 'нету клана';
						$(th.path.list).html(txt);
					}
					
					autoSize();
				}

				API.call('post.getUser',data,ok,error);
			}
				
			/** Добавляем сообещние на страницу - все сообщения пржде чем показаться попадают сюда */
			function _appendMessage(id) {
				var txt		= '';
				txt	= t.html.standartBlock(id);
				$(t.path.list).append(txt);
				autoSize();
			}
			
			function _prependMessage(id) {
				var txt		= '';
				txt	= t.html.standartBlock(id);
				$(t.path.list).prepend(txt);
				autoSize();
			}
			
			/** подготавливаем экран - показываем нужный нам блок \ аватары и т.п. */
			function _prepareScreen() {
				t.self.showTab('user');
				
				/** рисуем аватары */
				var ava_1	= getUserAvatarLink(PLAYER.user_id,50);
				var ava_2	= getUserAvatarLink(t.user_id,50);
				
				$(t.path.ava_1).html(ava_1);
				$(t.path.ava_2).html(ava_2);
				
				$(t.path.main).html('');
				$(t.path.list).html('');
				
				_message_list	= {};
				_page		= 1;
				
				autoSize();
			}
			
			return t;
		}
		
		/** обработчик клановых сообщений */
		t.clanCorrespondence	= ccHandler(t);
		function ccHandler(self) {
			var t	= {};
			t.self		= self;
			t.user_id	= '';
			t.user_data	= {};
			t.path		= {
				'ava_1'		: '#message_clan .ava_1',
				'ava_2'		: '#message_clan .ava_2',
				'list'		: '#message_clan .list',
				'more'		: '#message_clan .read_more',
				'area'		: '#message_clan_area',
				'empty'		: '#message_clan .empty',
				'message_block'	: '#message_clan .message'
			};
			
			/** показываем экран переписки между кланом */
			t.show		= function() {
				if (SKIN.nowScreen() != SCREEN_MAIL)
					SKIN.main(SKIN.parse('mail/mail_main',{'show_screen':2}),SCREEN_MAIL);
				
				
				
				/** если у пользователя нет клана -показываем пустую заглушку */
				if (PLAYER.profile.getInfo('clan_id') < 1) {
					t.self.showTab('clan');
					_empty();
					$(this.path.message_block).addClass('hidden');
					$(this.path.empty).css({'padding-top':'183px','padding-bottom':'183px'});
					return false;
				} else {
					$(this.path.message_block).remove('hidden');
					_prepareScreen();
					_load();	
				}
			}
			
			/** обновить список сообщений */
			t.refresh	= function() {
				_prepareScreen();
				_load();
			}
			
			/** кликнули показать еще */
			t.more		= function() {			
				_page++;
				_load();
			}
			
			/** отправить сообщение */
			t.send		= function() {
				var txt		= $(this.path.area).val();

				if (txt == '')
					return false;

				var data	= {
					'message'	:txt
				};

				/** отправляем сообщение на сервер */
				API.call('post.sendClan',data,function(r){
					_addMessage(r.id,{
						'author_id'	: PLAYER.user_id,
						'text'		: nl2br(txt),
						'id'		: r.id
					},'prepend');
					$(t.path.area).val('');
				},function(r){
					/** сообщение об ошибке */
					bAlert({
						'time'		: 3000,
						'title'		: g('error.post_balert_error_title'),
						'text'		: g('error.post_send_'+r.code)
					});
				});
			}
			
			/** все шаблоны */
			t.html		= htmlHandler(t);
			function htmlHandler(self) {
				var t	= {};
				t.self	= self;

				t.standartBlock		= function(id) {
					var info	= _message_list[id];
					var avatar_html	= getUserAvatarLink(info['author_id'],50,'i');
					var title	= g('location.post_user_title',{'from':getUserLink(info.author_id)});
				
					var replace	= {
						'id'		: info.id,
						'avatar_html'	: avatar_html,
						'title'		: title,
						'text'		: info.text,
						'last_update'	: till(info.last_update),
						'title1'	: g('global.delete'),
						'cls'		: info.author_id == PLAYER.user_id ? '' : 'log_bgr1'
					};
					
					var txt	= '\n\
					<div class="message clear_fix {cls}" id="message_{id}" rel="{id}">\n\
						<div class="message_checkbox hidden fl_l"></div>\n\
						<div class="message_inside pt10 pl10 pr10 pb8">\n\
							<div class="fl_l mr10">{avatar_html}</div>\n\
							<div class="message_data fl_l">\n\
								<div class="message_title">{title}</div>\n\
								<div class="message_description">{text}</div>\n\
								<div class="message_till">{last_update}</div>\n\
							</div>\n\
						</div>\n\
					</div>';
					return txt.format(replace);
				}
				
				return t;
			}
			
			/**
			 * -----------------------------------------------------
			 *			PROTECTED
			 * -----------------------------------------------------
			 **/
			
			var _message_list	= {};	// список сообщений между пользователями 
			var _page		= 1;
			
			/** удаляет выбранные сообщения */
			function _deleteMessage(id) {
				_message_list[id] = false;
				$('#message_'+id).animate({'height':0},200,function(){$(this).remove();autoSize();});
			}

			/** единственная точка добавления сообщений */
			function _addMessage(id,data,mode) {
				$(t.path.empty).addClass('hidden');
				
				if (typeof data.last_update == 'undefined') 
					data.last_update	= data.id;
				
				mode	= mode || 'append';
				_message_list[id] = data;
				
				if (mode ==='prepend') {
					_prependMessage(id);
				} else {
					_appendMessage(id);
				}
				
				autoSize();
			}
			
			/** грузим сообщения с сервера */
			function _load() {
				var th		= t;	
				var data	= {
					'page'		: _page
				};

				/** обнуляем счетчики */
				$('#counter_group2').html('');
				
				var ok		= function(r) {	
					if (count(r.messages) == 0 && _page == 1) {
						_empty();
					} else {
						/** добавляем полученные сообщения в локальную базу и там же показываем */
						for (var i in r.messages) {
							_addMessage(i,r.messages[i]);
						}
					}

					/** смотрим сколько страниц, показываем \ скрываем блок "показать еще" */
					if (r.params.pages > _page) {
						$(th.path.more).removeClass('hidden');
					} else {
						$(th.path.more).addClass('hidden');
					}
					
				}

				var error	= function(r) {
					if (r.code == 5) {
						var txt = 'нету клана';
						$(th.path.list).html(txt);
					}
				}

				API.call('post.getClan',data,ok,error);
			}
				
			/** Добавляем сообещние на страницу - все сообщения пржде чем показаться попадают сюда */
			function _appendMessage(id) {
				var txt		= '';
				txt	= t.html.standartBlock(id);
				$(t.path.list).append(txt);
				autoSize();
			}
			
			function _prependMessage(id) {
				var txt		= '';
				txt	= t.html.standartBlock(id);
				$(t.path.list).prepend(txt);
				autoSize();
			}
			
			/** подготавливаем экран - показываем нужный нам блок \ аватары и т.п. */
			function _prepareScreen() {
				t.self.showTab('clan');
				
				/** рисуем аватары */
				var ava_1	= getUserAvatarLink(PLAYER.user_id,50);
				var ava_2	= getClanAvatarLink();
				
				$(t.path.ava_1).html(ava_1);
				$(t.path.ava_2).html(ava_2);
				
				$(t.path.main).html('');
				$(t.path.list).html('');
				
				_message_list	= {};
				_page		= 1;
				autoSize();
			}
			
			function _empty() {
				var txt = '<div class="empty">' + g('location.post_clan_empty_list') + '</div>';
				$(t.path.list).html(txt);
				autoSize();
			}
			
			return t;
		}
		
		/** показать нужную область: main \ user \ clan */
		t.showTab		= function(name) {
			$(this.path.tab_main).addClass('hidden');
			$(this.path.tab_user).addClass('hidden');
			$(this.path.tab_clan).addClass('hidden');
			
			$(this.path['tab_'+name]).removeClass('hidden');
			autoSize();
		}
		
		/** обнулить все счетчики */
		t.resetCounter		= function() {
			var ok	= function() {
				bOk(g('location.mail_reset_counter_ok'));
				ACTIONS.mail.main.show();
			}
			API.call('post.resetCounter',{},ok);
		}
		
		return t;
	}
	
	t.mine		= mineHandler(t);
	function mineHandler(self) {
		var t	= {};
		t.self	= self;
		
		t.shop	= shopHandler(t);
		function shopHandler(self) {
			var t	= {
				'self'	: self
			}
			
			/** локальный кеш */
			var _cache	= {
				
			};
			
			/** возращает локальный кеш */
			t.getInfo	= function(key) {
				if (typeof _cache[key]!=='undefined')
					return _cache[key];
				
				return key;	
			}
			
			t.setCount	= function(id,count) {
				if (typeof _cache['count_all'] == 'undefined') {
					_cache['count_all']	= {};
				}
				_cache['count_all'][id]	= count;
			}
			
			/** показываем окно покупки */
			t.picks		= function(after_buy,button_title) {
				/** что нужно сделать после покупки */
				_cache['after_but']	= typeof after_buy!='undefined' ? after_buy : function(){};
				
				/** показываем Popup */
				var	ok	= function(r) {
					_cache.info	= r.info;
					
					var	vars	= {
						'vars'	: {
							'price'		: r.price,
							'button_text'	: typeof button_title !='undefined' ? button_title : g('location.mine_button_buy')
						}
					}

					/** в зависимости от гильдии - показываем разные popup  */
					if (r.type == 'standart') {
						/** стандартные очки */
						SKIN.popupShow(SKIN.parse('mine/mine_popup',vars));
					} else {
						/** для шахтеров */
						SKIN.popupShow(SKIN.parse('mine/mine_popup_mine',vars));
					}
				}

				API.call('mine.getPricePicks',{},ok);
			}
			
			/** купить */
			t.doPicks	= function() {
				/** оки */
				var ok		= function(r) {
					bOk(g('global.mine_buy_ok'));
					SKIN.popupClose();
					ACTIONS.mine.screenMain();
				}
				
				/** ошибки */
				var error	= function(r) {
					if (r.code	== ERROR_CODE_NO_MONEY) {
						noMoney();
					} else {
						bAlert(g('error.mine_'+r.code));
					}
				}
				
				API.call('mine.doPicks',{'count':_cache['count_all'],'price_type':ACTIONS.shop.getSelectedPriceType()},ok,error);
			}
			
			return t;
		}
		
		/** главная страница карьера */
		t.screenMain		= function() {
			/** ок можем работать*/
			var ok		= function(r) {
				if (PLAYER.work.getInfo('work_type') == WORK_TYPE_OPENING) {
					ACTIONS.mine.screenWork();
					return false;
				}
					
				
				var vars	= {
					vars	: {
						'stat'	: r.stat			
					}
				}
				SKIN.main(SKIN.parse('mine/mine_main',vars),SCREEN_MINE);
			}
			
			API.call('mine.getInfo',{},ok);
		}
		
		/** экран копания */
		t.screenWork		= function() {
			var vars	= {
				vars	: {
					'till'	: PLAYER.work.getInfo('work_end')
				}
			};
			SKIN.main(SKIN.parse('mine/mine_work',vars),SCREEN_MINE);
		}
		
		/** экран выбора что делать дальше */
		t.screenChoice		= function() {
			var vars	= {
				vars	: {
					'chance'	: PLAYER.cache.getInfo(JS_CACHE_MINE_CHOICE,mt_rand(1,100))
				}
			};
			SKIN.main(SKIN.parse('mine/mine_choice',vars),SCREEN_MINE_CHOICE);
		}
		
		/** пробуем начать копать */
		t.doDig		= function(mode) {
			/** если нет кирки - надо показать окно покупки */
			if (PLAYER.specials.getInfo('mine_1')<1) {
				ACTIONS.mine.shop.picks(function(){
					ACTIONS.mine.doDig(mode);
				},g('location.mine_do_buy_and_work'));
				return false;
			}
			
			/** начинаем копку */
			var ok		= function(r) {
				ACTIONS.mine.screenWork();
			}
			
			/** не можем копать */
			var error	= function(r) {
				bAlert(g('error.mine_'+r.code));
			}
			
			API.call('mine.doDig',{'mode':mode},ok,error);
		}
		
		/** отменяем работу - выходим из шахты не с чем */
		t.exitDig	= function() {
			var ok	= function() {
				ACTIONS.mine.screenMain();
			}
			
			API.call('mine.exitDig',{},ok,ok);
		}
		
		/** продолжаем копать дальше */
		t.restartDig	= function() {
			return ACTIONS.mine.doDig('restart');
		}
		
		/** пробуем выкопать кристал */
		t.tryDig	= function() {
			/** выкопали, не выкопали */
			var ok		= function(r) {
				mineAlert({
					'message'	: r.message,
					'action'	: function() {
						ACTIONS.mine.screenMain();
					}
				});
			}
			
			/** здесь не обрабатываем ошибки - просто показываем экран главной */
			var error	= function(r) {
				ACTIONS.mine.screenMain();
			}
			
			API.call('mine.tryDig',{},ok,error);
		}
		
		/** обнулить временную статистику */
		t.resetStat	= function() {
			var ok	= function() {
				ACTIONS.mine.screenMain();
			}
			API.call('mine.resetStat',{},ok,ok);
		}
		
		return t;
	}
	
	t.harbour	= harbourHandler(t);
	function harbourHandler(self) {
		var t	= {};
		t.self	= self;
		
		t.screenMain		= function() {
			return SKIN.main(SKIN.parse('harbour/harbour_main'));
		}
		
		return t;
	}
	
	t.clan		= clanHandler(t);
	function clanHandler(self) {
		var t	= {
			'self'	: self
		}
		
		/** главная страница клана */
		t.screenMain	= function() {
			if (intval(PLAYER.profile.getInfo('clan_id')) == 0) {
				/** экран вступления, основания */
					SKIN.main(SKIN.parse('clan/clan_empty'),SCREEN_CLAN_EMPTY);
			} else {
				/** экран показа главной клана */
				var ok		= function(r) {
					/** если вожак - расформировать клан */
					if (PLAYER.clan.isAllow(CLAN_USER_RANG_1)) {
						SKIN.setCrumbs({		
							'Клан'			: ''
						});
					} else {
						/** выйти из клана */
						SKIN.setCrumbs({		
							'Клан<div class="bold" style="top: -3px; right: -25px; position: absolute;" id="" onclick="ACTIONS.clan.leave();"><b class="icon16 settings" title=""></b>&nbsp;<span class="alink">Выйти из клана</span></div>' : ''
						});
					}
					
					SKIN.main(SKIN.parse('clan/clan_main'),SCREEN_CLAN_MAIN);
				} 
				
				var error	= function(r) {
					SKIN.main(SKIN.parse('clan/clan_empty'),SCREEN_CLAN_EMPTY);
				}
				
				API.call('clan.getInfo',{},ok,error);
			}
		}
		
		/** Экран (Popup) создания клана */
		t.screenMake	= function() {
			if (PLAYER.money.getInfo('money50') < 50)
				return noMoney();
			
			var txt	= SKIN.parse('clan/clan_make_alert');
			var p	= popup();
			
			p.add({
				'message'	: txt,
				'title'		: 'Основать клан',
				'width'		: 400,
				'button_yes'	: {
					'title'	: 'Основать',
					'action': function(){
						var name	= $('#clan_make_name').val();
						var tag		= $('#clan_make_tag').val();
						if (trim(name)=='')
							return;
						
						var ok		= function() {
							ACTIONS.clan.screenMain();
						}
						
						var error	= function(r) {
							if (r.code == 10 )
								return noMoney();
							bAlert(g('error.clan_'+r.code));
						}
						
						API.call('clan.make',{'name':name,'tag':tag},ok,error);
					}
				}
			}).show();
		}
		
		/** Экран (Popup) поиска клана */
		t.screenSearch	= function() {
			var txt	= SKIN.parse('clan/clan_search_alert');
			var p	= popup();
			
			p.add({
				'message'	: txt,
				'title'		: 'Найти клан',
				'width'		: 400
			}).show();
		}
		
		/** экран моего замка с описанием */
		t.screenCastle	= function() {
			var vars	= {
				'vars'	: {
					'about_html'	: PLAYER.clan.getInfo('about_html')
				}
			}
			SKIN.main(SKIN.parse('clan/clan_castle',vars));
		}
		
		/** плац */
		t.screenParade	= function(clan_id) {
			clan_id		= clan_id || PLAYER.profile.getInfo('clan_id');
			
			var ok		= function(r) {
				var vars	= {
					'vars'	: {
						'users'	: r.users,
						'new'	: r['new']
					}
				}
				SKIN.main(SKIN.parse('clan/clan_parade',vars));
			}
			
			var error	= function(r) {
				ACTIONS.clan.screenMain();
			}
			
			API.call('clan.getParadeInfo',{'clan_id':clan_id},ok,error);
		}
		
		/** тронный зал */
		t.screenRoom	= function() {
			var vars	= {
				'vars'	: {
					'about'		: PLAYER.clan.getInfo('about'),
					'name'		: PLAYER.clan.getInfo('name'),
					'tag'		: PLAYER.clan.getInfo('tag'),
					'site'		: PLAYER.clan.getInfo('site')
				}
			}
			
			SKIN.main(SKIN.parse('clan/clan_room',vars));
		}
		
		/** казначейство */
		t.screenTreasury= function() {		
			var ok	= function(r) {
				var vars	= {
					'vars'	: {
						'donate_list'	: r.donate_list
					}
				}
				SKIN.main(SKIN.parse('clan/clan_treasury',vars));
			}
			
			
			API.call('clan.getTreasuryInfo',{},ok);
		}
		
		/** экран выбора кланового логотипа */
		t.selectFlag	= function() {
			SKIN.popupShow(SKIN.parse('clan/clan_flag_popup'));
		}
		
		/** сохразняем выбранное изображение */
		t.doSelectFlag	= function() {
			var code	= GLOBAL.get('clan_flag');
			var ok		= function(r) {
				bOk(g('location.clan_select_flag_ok'));
				SKIN.popupClose();
				ACTIONS.clan.screenMain();
			}
			
			var error	= function() {
				bAlert(g('error.clan_'+r.code));
			}
			
			API.call('clan.doSelectFlag',{'code':code},ok,error);
		}
		
		/** добавить денег в казну */
		t.addTreasury	= function(type) {
			var amount	= intval($('#treasury_amount_'+type).val());
			if (amount < 1)
				return false;
			
			var data	= {
				'amount'	: amount,
				'type'		: type
			};
			
			var error	= function(r) {
				if (r.code == ERROR_CODE_NO_MONEY) 
					return noMoney();
				
				bAlert('error.clan_'+r.code);
			}
			
			var ok		= function(r) {
				bOk(g('clan.add_treasury_ok'));
				ACTIONS.clan.screenTreasury();
			}
			
			API.call('clan.addTreasury',data,ok,error);
		}
		
		/** сохранить информацию отредактированную в тронном зале */
		t.saveRoomInfo	= function() {
			var data	= { 
				'about'		: $('#clan_about_text').val(),
				'site'		: $('#clan_site').val(),
				'name'		: $('#clan_name').val(),
				'tag'		: $('#clan_tag').val()
			}
			
			/** */
			var ok		= function(r) {
				bOk(g('clan.save_room_info_ok'));
			}
			
			/** */
			var error	= function(r) {
				bAlert(g('error.clan_'+r.code));
			}
			
			API.call('clan.saveRoomeInfo',data,ok,error);
		}
		
		/** заявку на вступление */
		t.doSendAppToMembership	= function(clan_id) {
			var ok		= function(r) {
				bOk(g('clan.send_membership_ok'));
			}
			
			
			
			API.call('clan.doSendAppToMembership',{clan_id:clan_id},ok,t.error);
		}
		
		/** одобрить заявку в клан */
		t.appMembershipAccept	= function(user_id) {
			var ok		= function(r) {
				bOk(g('clan.app_membership_accept'));
				ACTIONS.clan.screenParade();
			}
			
			API.call('clan.appMembershipAccept',{'user_id':user_id},ok,t.error);
		}
		
		/** отклонить добровольца */
		t.appMembershipDecline	= function(user_id) {
			var ok		= function(r) {
				bOk(g('clan.app_membership_decline'));
				ACTIONS.clan.screenParade();
			}
			
			API.call('clan.appMembershipDecline',{'user_id':user_id},ok,t.error);
		}
		
		/** выйтииз клана - только не для Вожаков */
		t.leave			= function(force) {
			if (PLAYER.clan.isAllow(CLAN_USER_RANG_1)) {
				return false;
			}
			
			if (typeof force == 'undefined') {
				lConfirm({
					'message'	: 'Вы действительно хотите покинуть клан?',
					'action'	: function() {
						ACTIONS.clan.leave(true);
					}
				})
				
				return false;
			}
				
			/** */
			var ok	= function(r) {
				GLOBAL.reloadPage();
			}
				
			API.call('clan.leave',{},ok,ok);
		}
		
		/** удалить участника из клана */
		t.deleteMemberShip = function(user_id) {
			lConfirm({
				'message'	: 'Вы действительно хотите прогнать бойца?',
				'action'	: function() {
					var ok	= function() {
						ACTIONS.clan.screenParade();
					}
					API.call('clan.deleteMembership',{user_id:user_id},ok,ok);
				}
			})
		}
		
		/** стандартный обработчик */
		t.error		= function(r) {
			bAlert(g('error.clan_'+r.code));
		}
		
		return t;
	}
	
	t.clan_enemy	= clanEnemyHandler(t)
	function clanEnemyHandler(self) {
		var t	= {
			'self'	: self
		}
		
		var _cache	= {
			'info'	: {
				
			}
		}
		
		/** возвращает информацию о чужом клане */
		t.getInfo	= function(key) {
			key	= key || 'all';
			
			if (key === 'all' || typeof key == 'undefined')
				return _cache.info;
			
			if (typeof _cache.info[key]!=='undefined')
				return _cache.info[key];
			
			return key;
		}
		
		/** показываем чужой клан */
		t.show	= function(clan_id) {
			var ok		= function(r) {
				extend(_cache.info,r.info);
				
				var vars = {
					'vars'	: {
						'leader_name'	: getUserLink(r.info.leader_id),
						'about_html'	: _cache.info.about_html
					}
				}
				SKIN.main(SKIN.parse('clan_enemy/clan_enemy_main',vars));
			}
			
			var error	= function(r) {
				bAlert(g('error.clan_'+r.code));
			}
			
			API.call('clan.getClanInfo',{'clan_id':clan_id},ok,error);
		}
		
		
		return t;
	}
	
	t.gifts		= giftsHandler(t);
	function giftsHandler(self) {
		
		/** показывает мои подарки */
		t.me	= meHandler(t);
		function meHandler(self) {
			var t	= {
				'self'	: self,
				'path'	: {
					'list'	: '#gifts_block_list',
					'area'	: '#gifts_block_area',
					'more'	: '.read_more'
				}
			}
			
			/** */
			var _cache	= {
				'page'	: 1
			};
			
			/** показать список моих подарков */
			t.screenMain		= function(screen_num) {
				if (typeof screen_num == 'undefined')
					screen_num = 0;
				
				var vars	= {
					'vars'	: {
						'screen_num'	: screen_num
					}
				}
				SKIN.main(SKIN.parse('actions/gifts/gifts_main',vars));
				
				/** подгружаем подарки */
				_cache.page	= 1;
				_loadAndShow();
			}
			
			/** подгрузить еще подарков */
			t.more		= function() {
				_cache.page++;
				_loadAndShow();
			}
			
			/** удалить подарок */
			t.del		= function(id) {
				var load	= function(){
					$('.message[rel='+id+']').animate({'height':0},200,function(){$(this).remove();autoSize();});
				}
				API.call('gifts.delete',{'id':id},load,load);
			}
			
			/** храним все html шаблоны */
			t.html		= htmlHandler();
			function htmlHandler() {
				var t	= {}
				
				/** */
				t.emptyAreaBlock	= function() {
					var txt		= '<div class="square  fl_l"></div>';
					return txt;
				}
				
				/** */
				t.areaBlock	= function(gift_item) {
					var replace	= {
						'GIFT_ID'	: gift_item.gift_id,
						'IMG_URL'	: IMG_URL,
						'GIFT_IMG'	: gift_item.img
					};
					var txt		= '<div class="square  fl_l" onmouseover="TOOLTIP.hint(this,\'gift_{GIFT_ID}\');"><img class="w60 h60 dblock" src="{IMG_URL}/images/packs/gifts/{GIFT_IMG}" alt="" /></div>';
					return txt.format(replace);
				}
				
				/** */
				t.listBlock	= function(gift_item) {
					var title	= '';
					var last_update	= till(gift_item.id);
					
					/** формируем заголовок */
					if (gift_item.private_type == 2) {
						title	= g('location.gift_private_type_2');
					} else {
						title	= g('location.gift_private_type_'+gift_item.private_type).format({'USER_LINK':getUserLink(gift_item.author_id)});
					}

					/** формируем надпись снизу */
					if (gift_item.private_type == 2) {
						last_update	= last_update;
					} else {
						last_update	+= '&nbsp;|&nbsp;<span class="alink" onclick="ACTIONS.gifts.send.screeSendPopup(\'{USER_ID}\')">Отправить в ответ</span>'.format({'USER_ID':gift_item.author_id});
					}
					

					/** формируем падарок */
					var replace	= {
						'GIFT_ID'	: gift_item.gift_id,
						'IMG_URL'	: IMG_URL,
						'GIFT_IMG'	: gift_item.img
					};
					var gift_img	= '<div class="fl_l" onmouseover="TOOLTIP.hint(this,\'gift_{GIFT_ID}\');"><img class="w60 h60 dblock" src="{IMG_URL}/images/packs/gifts/{GIFT_IMG}" alt="" /></div>'.format(replace);
					
					var replace	= {
						'id'		: gift_item.id,
						'avatar_html'	: gift_img,
						'title'		: title,
						'text'		: gift_item.text,
						'last_update'	: last_update,
						'title1'	: g('global.delete')
					};
					
					var txt	= '\n\
					<div class="message clear_fix" id="gift_{id}" rel="{id}">\n\
						<div class="message_checkbox hidden fl_l"></div>\n\
						<div class="message_inside pt10 pl10 pr10 pb8" >\n\
							<div class="fl_l mr10">{avatar_html}</div>\n\
							<div class="message_data fl_l">\n\
								<div class="message_title">{title}</div>\n\
								<div class="message_description">{text}</div>\n\
								<div class="message_till">{last_update}</div>\n\
							</div>\n\
							<div class="post_close" title="{title1}" onclick="ACTIONS.gifts.me.del(\'{id}\');"></div>\n\
						</div>\n\
					</div>';
					return txt.format(replace);
				}
				
				return t;
			}
			
			/** пдогрузить и показать */
			function _loadAndShow() {
				var ok	= function(r) {
					if (r.more == 1) {
						$(t.path.more).removeClass('hidden');
					} else {
						$(t.path.more).addClass('hidden');
					}
					
					/** выводим подарки */
					var i	= 0;
					for(var key in r.list) {
						i++;
						var item	= r.list[key];
						$(t.path.area).append(t.html.areaBlock(item));
						$(t.path.list).append(t.html.listBlock(item));
					}
					
					for (var a=i;a<48;a++) {
						$(t.path.area).append(t.html.emptyAreaBlock());
					}
				}
				
				API.call('gifts.getMyGiftsList',{page:_cache.page},ok);
			}
			
			return t;
		}
		
		/** показывает мои подарки */
		t.enemy	= enemyHandler(t);
		function enemyHandler(self) {
			var t	= {
				'self'	: self,
				'path'	: {
					'list'	: '#gifts_block_list',
					'area'	: '#gifts_block_area',
					'more'	: '.read_more'
				}
			}
			
			/** */
			var _cache	= {
				'page'	: 1
			};
			
			/** показать список моих подарков */
			t.screenMain		= function(screen_num) {
				if (typeof screen_num == 'undefined')
					screen_num = 0;
				
				var vars	= {
					'vars'	: {
						'screen_num'	: screen_num
					}
				}
				SKIN.main(SKIN.parse('actions/gifts/gifts_enemy',vars));
				
				/** подгружаем подарки */
				_cache.page	= 1;
				_loadAndShow();
			}
			
			/** подгрузить еще подарков */
			t.more		= function() {
				_cache.page++;
				_loadAndShow();
			}
			
			/** храним все html шаблоны */
			t.html		= htmlHandler();
			function htmlHandler() {
				var t	= {}
				
				/** */
				t.emptyAreaBlock	= function() {
					var txt		= '<div class="square  fl_l"></div>';
					return txt;
				}
				
				/** */
				t.areaBlock	= function(gift_item) {
					var replace	= {
						'GIFT_ID'	: gift_item.gift_id,
						'IMG_URL'	: IMG_URL,
						'GIFT_IMG'	: gift_item.img
					};
					var txt		= '<div class="square  fl_l" onmouseover="TOOLTIP.hint(this,\'gift_{GIFT_ID}\');"><img class="w60 h60 dblock" src="{IMG_URL}/images/packs/gifts/{GIFT_IMG}" alt="" /></div>';
					return txt.format(replace);
				}
				
				/** */
				t.listBlock	= function(gift_item) {
					var title	= '';
					var last_update	= till(gift_item.id);
					
					/** формируем заголовок */
					if (gift_item.private_type == 0) {
						title	= g('location.gift_enemy_private_type_'+gift_item.private_type).format({'USER_LINK':getUserLink(gift_item.author_id)});
					} else {
						title	= g('location.gift_enemy_private_type_'+gift_item.private_type)
					}

					/** формируем падарок */
					var replace	= {
						'GIFT_ID'	: gift_item.gift_id,
						'IMG_URL'	: IMG_URL,
						'GIFT_IMG'	: gift_item.img
					};
					var gift_img	= '<div class="fl_l" onmouseover="TOOLTIP.hint(this,\'gift_{GIFT_ID}\');"><img class="w60 h60 dblock" src="{IMG_URL}/images/packs/gifts/{GIFT_IMG}" alt="" /></div>'.format(replace);
					
					var replace	= {
						'id'		: gift_item.id,
						'avatar_html'	: gift_img,
						'title'		: title,
						'text'		: gift_item.private_type == 0 ? gift_item.text : g('location.gift_enemy_decs_private_type_'+gift_item.private_type),
						'last_update'	: last_update
					};
					
					var txt	= '\n\
					<div class="message clear_fix" id="gift_{id}" rel="{id}">\n\
						<div class="message_checkbox hidden fl_l"></div>\n\
						<div class="message_inside pt10 pl10 pr10 pb8" >\n\
							<div class="fl_l mr10">{avatar_html}</div>\n\
							<div class="message_data fl_l">\n\
								<div class="message_title">{title}</div>\n\
								<div class="message_description">{text}</div>\n\
								<div class="message_till">{last_update}</div>\n\
							</div>\n\
						</div>\n\
					</div>';
					return txt.format(replace);
				}
				
				return t;
			}
			
			/** пдогрузить и показать */
			function _loadAndShow() {
				var ok	= function(r) {
					if (r.more == 1) {
						$(t.path.more).removeClass('hidden');
					} else {
						$(t.path.more).addClass('hidden');
					}
					
					/** выводим подарки */
					var i	= 0;
					for(var key in r.list) {
						i++;
						var item	= r.list[key];
						$(t.path.area).append(t.html.areaBlock(item));
						$(t.path.list).append(t.html.listBlock(item));
					}
					
					for (var a=i;a<48;a++) {
						$(t.path.area).append(t.html.emptyAreaBlock());
					}
				}
				
				API.call('gifts.getEnemyGiftsList',{page:_cache.page,'user_id':ENEMY.profile.getInfo('user_id')},ok);
			}
			
			return t;
		}
		
		/** обработчик popup отправки подарков */
		t.send	= sendHandler(t);
		function sendHandler(self) {
			var t	= {
				'self'	: self,
				'path'	: {
					'gifts_group'	: '#gifts_group_block',
					'gifts_send'	: '#gifts_send_block',
					'gift_price'	: '#chosen_gift_price',
					'gift_chosen'	: '#chosen_gift',
					'gifts_back'	: '#gift_back',
					'gifts_bonus'	: '#bonus_text'
				}
			}
		
			var _cache	= {
				'user_id'	: 0,			
				'gift_id'	: 0,			
				'timeout_id'	: 0,	// ID обработчика 
				'now_group'	: 1,	// 
				'gift_data'	: {}	// храним конфиг подарков 
			};	
			
			/** показать Popup отправки */
			t.screeSendPopup	= function(user_id,after) {						
				after	= after	|| function(){};
				
				var ok	= function(r){				
					_cache.gift_data	= r.list;
					_cache.now_group	= 1;
					_cache.user_id		= user_id;
					var info		= USERJS.get(_cache.user_id);								

					SKIN.popupShow(SKIN.parse('actions/gifts/gifts_main_popup',{'info':info}));
					ACTIONS.gifts.send.giftSlider.start(_cache.gift_data);
					ACTIONS.gifts.send.onMouseLeave();

					after();
					autoSize();
				}

				API.call('gifts.getSendList',{},ok)			
			}

			/* обработчик слайдера подарков */
			t.giftSlider	= giftSliderHandler(t);
			function giftSliderHandler(self) {			
				var t	= {			
					'self'		: self,
					'data'		: [],
					'api'		: {},
					'now_group'	: 1
				};						

				/* настройки по умолчанию */
				var _param	= {						
					page		: 0,		// активная страница
					limit		: 24		// кол-во подарков на одну страницу
				}										

				/* старт */
				t.start		= function(list) {
					this.api	= {},
					this.now_group	= 1;
					if (count(t.data)<1) {
						_load(list);		// если хранилище не содержит данных - подгружаем
					} else {
						_initSlider();		// если содержит - запускаем плагин
					}
					//log('giftHandler has been started :)');
				}

				/* при клике "вперед" */
				t.next		= function() {			
					/* проверяем, нужно ли подгрузить подарки перед промоткой */
					var now_page = t.api[t.now_group].getSize(); // кол-во подарков в блоке .scrollable

					if (now_page * _param.limit < count(t.data[t.now_group])) { // если их меньше, чем в нашем хранилище - добавляем
						var txt	= _html(now_page * _param.limit);
						t.api[t.now_group].addItem(txt).end();
						//log(now_page * _param.limit + ' gifts has been added :)')
					} else {				
						t.api[t.now_group].next();	// проматываем вперед					
					}
				}

				/* при клике "назад" */
				t.prev		= function() {
					t.api[t.now_group].prev();		// проматываем назад			}
				}

				/** при смене вкладки */
				t.onChangeGroup	= function(new_group) {
					this.now_group	= new_group;
					if(typeof this.api[this.now_group] == 'undefined'){
						_initSlider();					
					} 				
					//log('Group changed to: '+t.now_group);	
				}

				/* получаем данные */
				function _load(list) {													
					t.data	= list;
					_initSlider();				
				}

				/* запускаем плагин */
				function _initSlider() {			
					var txt	= _html(0);
					var path = '#gift_group_'+t.now_group+' .scrollable';
					$(path).find('.area').html(txt); // находим блок .area и заполняем его
					$(path).scrollable({
						items: '#gift_group_'+t.now_group+' .items',
						circular:true,
						'next':'*next',
						'prev':'*prev'
					}); // запускаем плагин
					t.api[t.now_group]	= $(path).data("scrollable");  // заносим значение api в хранилище				
				}

				/* шаблон подарка */		
				function _html(a) {
					/** наща задача вернуть подарки только от А до Б */
					a	= a;
					var b	= a + _param.limit;
					var i = 0;	// счетчик
					var txt = '<div class="fl_l items">';
					for (var gift_id in t.data[t.now_group]) {
						// gift_id	- название значений в массиве типа 61, 62, 63...
						// i		- кол-во подарков в группе, например от 61 до 120
						// a		- id первого подарка в текущем экране
						// b		- максимальное кол-во подарков для текущего экрана

						i++;

						if (i < a)
							continue;

						if (i > b)
							break;

						txt	+= '<div class="square active_square fl_l" onmouseover="ACTIONS.gifts.send.onMouseOver('+ gift_id +'); TOOLTIP.hint(this,\'gift_'+ gift_id +'\');" onmouseleave="ACTIONS.gifts.send.onMouseLeave();" onclick="ACTIONS.gifts.send.onMouseClick('+ gift_id +', this);"><img class="w60 h60 dblock" src="'+ IMG_URL +'/images/packs/gifts/'+ t.data[t.now_group][gift_id].img +'" alt="" /></div>'
					}

					/* если кол-во подарков на последнем экране меньше максимального - заполняем пустышками */
					var c = b - i; // сколько нам не хватило подарков чтобы заполнить область						
					for (var i=0; i<=c; i++) {
						txt	+= '<div class="square fl_l"></div>';
					}

					txt	+= '</div>';
					return txt;
				}						

				return t;

			}	

			/* переключаем группы подарков при клике по табам */
			t.changeGroup	= function(new_group){				
				_cache.now_group	= new_group;		
				ACTIONS.gifts.send.giftSlider.onChangeGroup(new_group);	
				autoSize();
			}

			/* показываем цену при наведении курсора мыши */
			t.onMouseOver		= function(gift_id) {
				var gift	= _cache.gift_data[_cache.now_group][gift_id];
				$('#gift_price').html(_getPriceInfo(gift.price));

				/* очищаем текущий отложенный, чтобы он не изменил нашу цену */
				clearTimeout(_cache['timeout_id']);
			}

			/* когда убираем курсор - очищаем цену */
			t.onMouseLeave		= function() {
				var price	= {
					type2 : {
							'money2'	:0
						},
					type3 : {
							'money3'	:0
						}
				};

				/* очищаем предыдущий обработчик - чтобы они не накапливались!! */
				clearTimeout(_cache['timeout_id']);
				_cache['timeout_id'] = setTimeout(function(){
					$('#gift_price').html(_getPriceInfo(price));
				},300);
			}

			/* кликаем по подарку */
			t.onMouseClick		= function(gift_id) {
				clearTimeout(_cache['timeout_id']);
				var gift	= _cache.gift_data[_cache.now_group][gift_id];
				$(this.path.gifts_group).addClass('hidden'); // скрываем подарки
				$(this.path.gifts_send).removeClass('hidden'); // показываем окно покупки подарка
				$(this.path.gift_price).html(ACTIONS.shop.html.priceBlock(gift.price)); // выводим цену выбранного подарка
				$(this.path.gifts_back).removeClass('hidden'); // показываем кнопку "назад"

				//log('We chose the gift number: '+gift_id);

				var replace	= {
					'IMG_URL'	: IMG_URL,
					'GIFT_ID'	: gift_id,
					'IMG_GIFT'	: gift.img
				};			
				
				_cache.gift_id	= gift_id;
				
				/* выводим иконку подарка */
				var txt		= '<img class="w60 h60 dblock" src="{IMG_URL}/images/packs/gifts/{IMG_GIFT}" alt="" onmouseover="TOOLTIP.hint(this,\'gift_{GIFT_ID}\');" />'.format(replace);
				$(this.path.gift_chosen).html(txt);	
				$(this.path.gifts_bonus).html('');
				ACTIONS.gifts.send.getBonusTxt(gift_id);

				autoSize();
				clearTimeout(_cache['timeout_id']);
			}

			/** вернуться обратно на стираницу со списком подарков */
			t.giftBack		= function(){
				$(this.path.gifts_send).addClass('hidden'); // скрываем окно покупки подарка
				$(this.path.gifts_back).addClass('hidden'); // скрываем кнопку "назад"
				$(this.path.gifts_group).removeClass('hidden'); // показываем подарки			
			}

			/** подарить подарок */
			t.doSend		= function() {
				var ok	= function(r) {
					bOk(g('location.gift_send_ok'));
					SKIN.popupClose();	
					
					if (SKIN.nowScreen() == SCREEN_ENEMY) {
						ENEMY.profile.screenMain();
					}
				}
				
				var error	= function(r) {
					if (r.code) {
						noMoney();
						return false;
					}
				}
				
				var send_data	= {
					'text'		: $('#send_gift_text').val(),
					'private_type'	: $('input[name=private_type]:checked').val(),
					'price_type'	: ACTIONS.shop.getSelectedPriceType(),
					'gift_id'	: _cache.gift_id,
					'user_id'	: _cache.user_id
				};
				
				API.call('gifts.send',send_data,ok,error);
			}

			/* возвращает из кеши инфу */
			t.getInfo		= function(key) {
				if (typeof key == 'undefined')
					return _cache;

				if (typeof _cache[key]!=='undefined')
					return _cache[key];

				return key;
			}
			
			/** */
			t.showSendPopup		= function(user_id,gift_id) {
				this.screeSendPopup(user_id,function() {
					ACTIONS.gifts.send.changeGroup(4);
					ACTIONS.gifts.send.onMouseClick(gift_id);
					ACTIONS.gifts.send.getBonusTxt(gift_id);
				});
			}
			
			/** */
			t.getBonusTxt		= function(gift_id) {
				var bonus_id	= 0;
				
				if (PLAYER.actions.isActive('knowlege_day')) {
					var offset	= 258;

					if (gift_id > offset && gift_id <=266) 
						bonus_id	= gift_id - offset;
				}
				
				if (bonus_id == 0)
					return '';
				
				$(this.path.gifts_bonus).html(g('location.gift_bonus_'+bonus_id));
				
				
			}
			
			function _getPriceInfo(price) {
				var txt = "{M2} <b class='icon money2' title='Кристаллы'></b>&nbsp;\\&nbsp; {M3} <b class='icon money3' title='Зелень'></b>";
				return txt.format({
					'M2'	: price.type2.money2,
					'M3'	: price.type3.money3
				});
			}
			
			
			return t;
		} // send
		
		return t;
	}
	
	t.rating	= ratingHandler(t);
	function ratingHandler(self) {
		var t	= {
			'self'	: self,
			'path'	: {
				'main'		: '#path_rating',
				'my_info'	: '#path_my_info',
				'more'		: '#path_rating_more'
			},
			'param'	: {
				'limit'	: 20	// кол-во записей на одну страницу 
			}
		};
		
		var _cache = {
			data	: []		// user_id
		}
		
		/** главный экран рейтинга */
		t.show		= function() {
			$(this.path.main).html('');
			$(this.path.my_info).html('');
			_cache['data']		= [];
			_cache['offset']	= 0;
			
			_loadAndShow();
		}
		
		/** показать еще */
		t.more		= function() {
			_cache['offset']	+= this.param.limit;
			_loadAndShow();
		}
		
		/** набор html элементов */
		t.html		= htmlHandler();
		function htmlHandler(self) {
			var t	= {
				'self'	: self
			}
			
			/** показываем стандартный блок */
			t.standartBlock		= function(user_id,position) {
				var user	= USERJS.get(user_id);
				if (!user)
					return '';
				
				var replace	= {
					'POSITION'	: position,
					'AVATAR_SRC'	: getUserAvatarLink(user_id,50,'i'),
					'NAME'		: user.name,
					'LEVEL'		: user.level,
					'CLAN'		: getUserClanLink(user_id),
					'CITY_AGE'	: user.city_age,
					'POWER'		: user.power,
					'BLOCK'		: user.block,
					'ENDURANCE'	: user.endurance,
					'CHARISMA'	: user.charisma,
					'DEXTERITY'	: user.dexterity,
					'RATING_CLASS'	: user.rating_class,
					'RATING'	: digits(user.rating),
					'RATING_PERCENT': user.rating_percent
				}
				
				if (position <= 3) {
					replace.CLS	= 'rating_bgr' + position;
					
				} else{
					replace.CLS	= position % 2 == 1 ? 'rating_bgr0' : '';
				}
				
				if (PLAYER.profile.getInfo('user_id') == user_id) {
					replace.CLS	= 'rating_me';
				}
				
				var txt = '\n\
					<div class="active_square clear_fix border3 pr5 pt8 pb8 mt-1 {CLS}">\n\
						<div class="fl_l">\n\
							<div class="pt18 w20 f_s10 middlebrown center">{POSITION}</div>\n\
						</div>\n\
						<div class="fl_l dblock_img mr10">\n\
							{AVATAR_SRC}\n\
						</div>\n\
						<div class="w160 fl_l">\n\
							<div class="bold">{NAME} <b class="icon16 char_stat_level" title="Уровень"></b>{LEVEL}</div>\n\
							<div class="mb3">{CLAN}</div>\n\
							<div class="anotherbrown">' + g('icon.char_stat_home') + '{CITY_AGE}</div>\n\
						</div>\n\
						<div class="fl_l">\n\
							<div class="pl5 anotherbrown clear_fix mb2">\n\
								<div class="village_shop_item_stat pt3 ml-13">\n\
									<div class="fl_l">\n\
										<div class="pl11 pr11">\n\
											<b title="Сила" class="icon16 stat_power"></b>\n\
										</div>\n\
										<div class="f_s10 center pr2">{POWER}</div>\n\
									</div> \n\
									<div class="fl_l">\n\
										<div class="pl11 pr11">\n\
											<b title="Защита" class="icon16 stat_block "></b>\n\
										</div>\n\
										<div class="f_s10 center pr2">{BLOCK}</div>\n\
									</div> \n\
									<div class="fl_l">\n\
										<div class="pl11 pr11">\n\
											<b title="Ловкость" class="icon16 stat_dexterity"></b>\n\
										</div>\n\
										<div class="f_s10 center pr2">{DEXTERITY}</div>\n\
									</div>\n\
									<div class="fl_l">\n\
										<div class="pl11 pr11">\n\
											<b title="Масса" class="icon16 stat_endurance"></b>\n\
										</div>\n\
										<div class="f_s10 center pr2">{ENDURANCE}</div>\n\
									</div>\n\
									<div class="fl_l">\n\
										<div class="pl11 pr11">\n\
											<b title="Мастерство" class="icon16 stat_charisma"></b>\n\
										</div>\n\
										<div class="f_s10 center pr2">{CHARISMA}</div>\n\
									</div>\n\
								</div>\n\
							</div>\n\
							<div class="rating_ouside w180">\n\
								<div class="rating rating{RATING_CLASS}" >\n\
									<div style="width: {RATING_PERCENT}%;"></div>\n\
									<b></b>\n\
									<span>{RATING}</span>\n\
								</div>\n\
							</div>\n\
						</div>\n\
						<div class="fl_r pt17 bold">\n\
							{RATING} ' + g('icon.rating') + '\n\
						</div>\n\
					</div>';
				
				return txt.format(replace);
			}
			
			/** показываем блоки в иформации обо мне */
			t.myBlock		= function(user_id,position,position_yesterday) {
				var user	= USERJS.get(user_id);
				if (!user)
					return '';
				
				var replace	= {
					'POSITION'	: position,
					'AVATAR_SRC'	: getUserAvatarLink(user_id,50,'i'),
					'NAME'		: user.name,
					'LEVEL'		: user.level,
					'CLAN'		: getUserClanLink(user_id),
					'CITY_AGE'	: user.city_age,
					'POWER'		: user.power,
					'BLOCK'		: user.block,
					'ENDURANCE'	: user.endurance,
					'CHARISMA'	: user.charisma,
					'DEXTERITY'	: user.dexterity,
					'RATING_CLASS'	: user.rating_class,
					'RATING'	: digits(user.rating),
					'RATING_PERCENT': user.rating_percent
					
				}
				
				if (position == position_yesterday) {
					replace.INC_POSITION	= g('icon.char_stat_levelup') + 'Позиции без изменений' ;
				} else if (position > position_yesterday) {
					replace.INC_POSITION	= g('icon.arrow_red') + '<span class="red">- '+limit(position - position_yesterday,1) + get_pos(limit(position - position_yesterday,1))+'</span>';
				} else {
					// если позиция стала выше
					replace.INC_POSITION	= g('icon.arrow_green') + '<span class="green">+ '+limit(position - position_yesterday,1) + get_pos(limit(position - position_yesterday,1))+'!</span>';
				}
				
				if (position <= 3) {
					replace.CLS	= 'rating_bgr' + position;
					
				} else{
					replace.CLS	= position % 2 == 1 ? 'rating_bgr0' : '';
				}
				
				if (PLAYER.profile.getInfo('user_id') == user_id) {
					replace.CLS	= 'rating_me';
				}
				
				var txt = '\n\
					<div class="active_square clear_fix border3 pr5 pt8 pb8 mt-1 {CLS}">\n\
						<div class="fl_l">\n\
							<div class="pt18 w20 f_s10 middlebrown center">{POSITION}</div>\n\
						</div>\n\
						<div class="fl_l dblock_img mr10">\n\
							{AVATAR_SRC}\n\
						</div>\n\
						<div class="w160 fl_l">\n\
							<div class="bold">{NAME} <b class="icon16 char_stat_level" title="Уровень"></b>{LEVEL}</div>\n\
							<div class="mb3">{INC_POSITION}</div>\n\
						</div>\n\
						<div class="fl_l">\n\
							<div class="pl5 anotherbrown clear_fix mb2">\n\
								<div class="village_shop_item_stat pt3 ml-13">\n\
									<div class="fl_l">\n\
										<div class="pl11 pr11">\n\
											<b title="Сила" class="icon16 stat_power"></b>\n\
										</div>\n\
										<div class="f_s10 center pr2">{POWER}</div>\n\
									</div> \n\
									<div class="fl_l">\n\
										<div class="pl11 pr11">\n\
											<b title="Защита" class="icon16 stat_block "></b>\n\
										</div>\n\
										<div class="f_s10 center pr2">{BLOCK}</div>\n\
									</div> \n\
									<div class="fl_l">\n\
										<div class="pl11 pr11">\n\
											<b title="Ловкость" class="icon16 stat_dexterity"></b>\n\
										</div>\n\
										<div class="f_s10 center pr2">{DEXTERITY}</div>\n\
									</div>\n\
									<div class="fl_l">\n\
										<div class="pl11 pr11">\n\
											<b title="Масса" class="icon16 stat_endurance"></b>\n\
										</div>\n\
										<div class="f_s10 center pr2">{ENDURANCE}</div>\n\
									</div>\n\
									<div class="fl_l">\n\
										<div class="pl11 pr11">\n\
											<b title="Мастерство" class="icon16 stat_charisma"></b>\n\
										</div>\n\
										<div class="f_s10 center pr2">{CHARISMA}</div>\n\
									</div>\n\
								</div>\n\
							</div>\n\
							<div class="rating_ouside w180">\n\
								<div class="rating rating{RATING_CLASS}" >\n\
									<div style="width: {RATING_PERCENT}%;"></div>\n\
									<b></b>\n\
									<span>{RATING}</span>\n\
								</div>\n\
							</div>\n\
						</div>\n\
						<div class="fl_r pt17 bold">\n\
							{RATING} ' + g('icon.rating') + '\n\
						</div>\n\
					</div>';
				
				return txt.format(replace);
			}
			
			return t;
		}
		
		/**
		* -----------------------------------------------------
		*			PROTECTED
		* -----------------------------------------------------
		**/

		/** отрисовываем главный экран */
		function _mainScreen(r) {
			SKIN.main(SKIN.parse('rating/rating_main',r),SCREEN_RATING);
		}

		/** загрузить и показать */
		function _loadAndShow() {
			var onLoad	= function(r){
				for(var key in r.data) {
					_cache['data'].push(r.data[key]);
				}

				if (SKIN.nowScreen() != SCREEN_RATING)
					_mainScreen(r);

				/** если есть информация обо мне */
				if (typeof r.my_info != 'undefined') {
					_showMyInfo(r.my_info);
				}
				
				_show();
			}

			var data	= {
				'offset'	: _cache['offset']
			}

			API.call('rating.getList',data,onLoad);
		}

		/** показываем нужным нам элементы */
		function _show() {
			var max	= _cache['offset'] + t.param.limit;

			for(var a = _cache['offset'];a<= max ;a++) {
				if (typeof _cache['data'][a] == 'undefined')
					continue;

				var txt = t.html.standartBlock(_cache['data'][a],a+1);
				$(t.path.main).append(txt);
			}

			//log(count(_cache['data']));
			//log(max);
			if (count(_cache['data']) < max) {
				$(t.path.more).addClass('hidden');
			} else {
				$(t.path.more).removeClass('hidden');
			}
			
			autoSize();
		}
		
		/** показывает информацию обо мне */
		function _showMyInfo(info) {
			//log(info);
			for(var i in info.users) {
				var value	= info.users[i];
				var user	= USERJS.get(value.user_id);
				//log(user);
				//log(value);
				if (user == false)
					continue;

				if (value.user_id == PLAYER.profile.getInfo('user_id'))
					var txt = t.html.myBlock(value.user_id,value.rating_rank,info.yesterday);
				else
					var txt = t.html.standartBlock(value.user_id,value.rating_rank);
				
				$(t.path.my_info).append(txt);
			}
		}
		
		return t;
	}
	
	t.monster	= monsterHandler(t);
	function monsterHandler(self) {
		var t	= {
			'self'	: self
		}
		
		/** показываем чужого монстра */
		t.showEnemy	= function(enemy_id) {
			var ok		= function(r) {
				if (r.type == 'active') {
					/** если активный монстр */
					var vars	= {
						'vars'	: {
							'enemy_id'	: enemy_id,
							'info'		: r.info,
							'friend_info'	: r.friend_info
						}
					}
					
					SKIN.main(SKIN.parse('actions/monster/monster_enemy',vars));
				} else {
					/** если монстр мерт */
					var vars	= {
						'vars'	: {
							'enemy_id'	: enemy_id,
							'info'		: r.info,
							'friend_info'	: r.friend_info
						}
					}					
					SKIN.main(SKIN.parse('actions/monster/monster_enemy_dead',vars));
				}				
			}

			API.call('monster.getEnemy',{'enemy_id':enemy_id},ok,this.error);
		}
		
		/** показываем моего монстра */
		t.screenMain	= function() {
			/**  */
			if (PLAYER.profile.getInfo('level')<5) {
				this.error({code:4});
				return false;
			}
			
			if (getSettings(JS_SETTINGS_TUTORIAL_BEGIN_STEP25,null)!=1) {
				this.error({code:5});
				return false;
			}
			
			var ok		= function(r) {
				if (r.type == 'active') {
					/** если активный монстр */
					var vars	= {
						'vars'	: {
							'info'		: r.info,
							'friend_info'	: r.friend_info
						}
					}
					
					SKIN.main(SKIN.parse('actions/monster/monster_main',vars),SCREEN_MONSTER);
				} else {
					/** если монстр мерт */
					var vars	= {
						'vars'	: {
							'info'		: r.info,
							'friend_info'	: r.friend_info
						}
					}					
					SKIN.main(SKIN.parse('actions/monster/monster_dead',vars));
				}
				
			}
			
			API.call('monster.getInfo',{},ok,this.error);
		}
		
		/** отправляем уведомление другу - чтобы тот пинул монстра */
		t.doSendFriendNotice	= function(user_id) {
			/** фикс для одноклассников */
			if (SERVER_OS == 'ok') {
				this.okInvite();
				return false;
			}
			
			var ok		= function(r) {
				bAlert({
					'title'	: g('global.b_ok_title'),
					'text'	: g('location.monster_send_friend_notice'),
					'time'	: 500
				});
			}
				
			API.call('monster.sendFriendNotice',{'user_id':user_id},ok,this.error);
		}
		
		/** постим себе */
		t.postMe		= function(monster_id) {
			var data	= {
				'image_id'	: 'monster_' + monster_id,
				'message'	: g('global.vk_monster_post_me')
			}
			
			if (PLAYER.cache.get(JS_CACHE_CAN_BLOT)==1) {
				data['need_blot']	= true;
				data['blot_type']	= 'standart';
			}
			
			SOCIAL.friends.postMyWall(data);
		}
		
		/** постим другу */
		t.postFriend		= function(monster_id) {
			SOCIAL.friends.postFriendWall({
				'image_id'	: 'monster_' + monster_id,
				'message'	: g('global.vk_monster_post_friend')
			});
		}
		
		/** пинаем чужого */
		t.doKickEnemy		= function(enemy_id) {
			var ok		= function(r) {
				ACTIONS.monster.showEnemy(enemy_id);
			}
			
			API.call('monster.doKickEnemy',{'enemy_id':enemy_id},ok,this.error);	
		}
		
		/** позвать друзей попинать монстра */
		t.inviteVk		= function(reciver_id,monster_id) {
			var data	= {
				'image_id'	: 'monster_' + monster_id,
				'message'	: g('global.vk_monster_post_friend'),
				'stat'		: 'about_monster',
				'reciver_id'	: reciver_id
			}
			SOCIAL.friends.postWall(data);
		}
		
		/** я сам пинаю своего монстра */
		t.doKick		= function() {
			var ok	= function(r)  {
				ACTIONS.monster.screenMain();
			}
			API.call('monster.doKick',{},ok,this.error);
		}
		
		/** стандартный обработчик */
		t.error			= function(r) {
			bAlert(g('error.monster_'+r.code));
		}
		
		/** позвать друзей на одноклассниках */
		t.okInvite		= function() {
			GLOBAL.set(GLOBAL_GET_FAPI_CONFIRM,function(data) {
				/** отправляем для статистики пополнения денег на сервер */
				API.call('service.statTell',{'key':'invite_friend'});
			});
			FAPI.UI.showNotification(g('global.ok_monster'),'monster'+PLAYER.profile.getInfo('user_id'));
		}
		
		return t;
	}
	
	t.horn		= hornHandler(t); 
	function hornHandler(self) {
		var t	= {
			'self'	: self
		}
		
		/** главный экран рога */
		t.screenMain	= function() {
//			if ( !(PLAYER.profile.getInfo('level')>=3 && PLAYER.stat.getInfo('watch')>=24)) {
//				this.error({code:2});
//				return false;
//			}
			
			if ( !(getSettings(JS_SETTINGS_TUTORIAL_BEGIN_STEP24,null)==1)) {
				this.error({code:3});
				return false;
			}
			 
			
			var ok	= function(r) {
				var vars	= {
					'vars'	: {
						'info'		: r.info,
						'list'		: r.list,
						'friend_info'	: r.friend_info
					}
				}
				SKIN.main(SKIN.parse('actions/horn/horn_main',vars),SCREEN_HORN);
			}
			
			API.call('horn.getInfo',{},ok,this.error);
		}
		
		/** постим себе */
		t.postMe		= function() {
			setSettings(JS_SETTINGS_HORN_INVITE_OPEN,1);
			
			var data	= {
				'image_id'	: 'horn',
				'message'	: g('global.vk_horn_post_me')
			}
			 
			if (PLAYER.cache.get(JS_CACHE_CAN_BLOT)==1) {
				data['need_blot']	= true;
				data['blot_type']	= 'standart';
			}
			
			SOCIAL.friends.postMyWall(data);
		}
		
		/** постим другу */
		t.postFriend		= function(user_id) {
			setSettings(JS_SETTINGS_HORN_INVITE_OPEN,1);
			
			/** фикс для одноклассников */
			if (SERVER_OS == 'ok') {
				this.okInvite();
				return false;
			}
			
			if (typeof user_id != 'undefined') {
				SOCIAL.friends.postWall({
					'image_id'	: 'horn',
					'message'	: g('global.vk_horn_post_frined'),
					'reciver_id'	: user_id
				});
			} else {
				SOCIAL.friends.postFriendWall({
					'image_id'	: 'horn',
					'message'	: g('global.vk_horn_post_frined')
				});
			}
		}
		
		/** собрать кристальный урожай */
		t.doCrop		= function() {
			var ok		= function(r) {
				bOk(g('location.horn_crop_ok'));
				ACTIONS.horn.screenMain();
			}
			
			API.call('horn.doCrop',{},ok,this.error);
		}
		
		/** позвать друзей на одноклассниках */
		t.okInvite		= function() {
			setSettings(JS_SETTINGS_HORN_INVITE_OPEN,1);
			GLOBAL.set(GLOBAL_GET_FAPI_CONFIRM,function(data) {
				/** отправляем для статистики пополнения денег на сервер */
				API.call('service.statTell',{'key':'invite_friend'});
			});
			FAPI.UI.showNotification(g('global.ok_invite_friend'),'customAttr=vValue');
		}
		
		t.error			= function(r) {
			bAlert(g('error.horn_'+r.code));
		}
		return t;
	}
	
	/** обработчик квестов и дейликов */
	t.quest		= questHandler(t);
	function questHandler(self) {
		var t	= {
			'self'	: self
		}
		
		/** главный экран выбора квестов */
		t.screenMain	= function() {
			var ok	= function(r) {
				var vars	= {
					'vars'	: r
				}
				SKIN.main(SKIN.parse('actions/quest/quest_main',vars),SCREEN_QUEST);
			}
			
			API.call('quest.getInfo',{},ok,this.error);
		}
		
		/** */
		t.showInfo	= function(quest_id) {
			var ok	= function(r) {
				var p	= popup();
				p.add({
					'message'	: r.txt,
					'title'		: r.name,
					'width'		: 450
				});
				
				/** если можно окончить */
				if (r.status == 0) {
					if (r.can_end == 1) {
						p.set({
							'button_yes'	: {
								'title'	: g('location.quest_try_end'),
								'action': function() {
									ACTIONS.quest.tryEnd(r.quest_id);
								}
							}
						});
					} else {
						p.set({
							'button_yes_gray'	: {
								'title'	: g('location.quest_try_end'),
								'action': function() {
									ACTIONS.quest.tryEnd(r.quest_id);
								}
							}
						});
					}
				}
				
				/** чтобы корректно отрабатывал ттутор */
				GLOBAL.set(ON_CLOSE_L_POPUP,function(){
					TUTORIAL.onClosePopup();
				});
				p.show();
			};
			
			API.call('quest.getInfo',{'quest_id':quest_id},ok,t.error);
		}
		
		/** пробуем завершить квест */
		t.tryEnd	= function(quest_id) {
			var ok	= function(r) {
				bOk(g('location.quest_end_ok'));
				lPopupRemove();
				ACTIONS.quest.screenMain();
			}
			
			API.call('quest.tryEnd',{'quest_id':quest_id},ok,t.error);
		}
		
		/** */
		t.error		= function(r) {
			bAlert(g('error.quest_'+r.code));
		}
		return t;
	}
	
	/** награды пользователя */
	t.honor		= honorHandler(t);
	function honorHandler(self) {
		var t	= {
			'self'	: self,
			'path'	: {
				'main'	: '#honor_main',
				'lists'	: '.path_list'
			}
		}
		
		/** мои награды */
		t.screenMain	= function(group) {
			group	= group || 1;
			
			var ok =function (r) {
				var vars	= {
					'vars'		: {
						content	: {
							'medals'	: SKIN.parse('actions/honor/honor_medals_include',{
								'vars'		: {
									'ar_all_medals'	: _getMedalsHtml(PLAYER.medals.getInfo()),
									'all_medals'	: PLAYER.medals.getInfo(),
									'status'	: r.status
								}
							}),
							'ordens'	:SKIN.parse('actions/honor/honor_ordens_include',{
								'vars'		: {
									'ar_all_ordens'	: _getOrdensHtml(PLAYER.ordens.getInfo()),
									'all_ordens'	: PLAYER.ordens.getInfo()
								}
							}),
							'stat'		:SKIN.parse('actions/honor/honor_stat_include',{})
						}
					}
				}
				
				if(MODULE_SPEC || MODULE_BLOT) {
					SKIN.setCrumbs({
						'Мой профиль'		: function(){ACTIONS.profile.screenMain()},
						'Мои награды<div class="" style="top: -3px; right: -25px; position: absolute;"  onclick="ACTIONS.booster.screenMain();"><span class="alink">Усилители</span></div>'		: ''
					});
				} else {
					SKIN.setCrumbs({
						'Мой профиль'		: function(){ACTIONS.profile.screenMain()},
						'Мои награды'		: ''
					});
				}
				
				SKIN.main(SKIN.parse('/actions/honor/honor_main',vars));
				t.showGroup(group);
			}
			
			API.call('profile.getMedalInfo',{},ok);
		}
		
		/** пересчитать полученные медали  */
		t.recountMedals	= function() {
			var ok	= function(r) {
				bOk(g('location.recount_medals_ok'));
				ACTIONS.honor.screenMain(1);
			}
			
			API.call('honor.recountMedals',{},ok,t.error);
		}
		
		/** пересчитать полученные ордена  */
		t.recountOrdens	= function() {
			var ok	= function(r) {
				bOk(g('location.recount_ordens_ok'));
				ACTIONS.honor.screenMain(2);
			}
			
			API.call('honor.recountOrdens',{},ok,t.error);
		}
		
		/** */
		t.error		= function(r) {
			bAlert(g('error.honor_'+r.code));
		}
		
		/**  переключаем группы */
		t.showGroup	= function(group_id) {
			$(this.path.main).find('.tabs_buttons .btn').removeClass('selected');
			$(this.path.main).find('.tabs_buttons .btn[name='+group_id+']').addClass('selected');
			
			$(this.path.lists).addClass('hidden');
			$('#honor_list_'+group_id).removeClass('hidden');
		}
		
		/** награды игрока */
		t.screenEnemy	= function(group) {
			group		= group || 1;
			var user_id	= ENEMY.profile.getInfo('user_id');
			
			var ok =function (r) {
				var vars	= {
					'vars'		: {
						content	: {
							'medals'	: SKIN.parse('actions/honor/honor_medals_include',{
								'vars'		: {
									'ar_all_medals'	: _getMedalsHtml(ENEMY.medals.getInfo()),
									'all_medals'	: ENEMY.medals.getInfo(),
									'status'	: r.status
								}
							}),
							'ordens'	:SKIN.parse('actions/honor/honor_ordens_include',{
								'vars'		: {
									'ar_all_ordens'	: _getOrdensHtml(ENEMY.ordens.getInfo()),
									'all_ordens'	: ENEMY.ordens.getInfo()
								}
							})
						}
					}
				}
				
				/** крошки для чужого профайла */
				var crumbs	= {};
				
				crumbs[ENEMY.profile.getInfo('name')]	= function(){ACTIONS.showProfile(user_id);},
				crumbs['Награды игрока']	= ''
				SKIN.setCrumbs(crumbs);
				
				/** показываем  */
				SKIN.main(SKIN.parse('/actions/honor/honor_main',vars));
				t.showGroup(group);
			}
			
			API.call('enemy.getMedalInfo',{'user_id':user_id},ok);
		}
		
		/** HTML массив с медалями */
		function _getMedalsHtml(ar_now) {
			var ar_all_medals	= [];
			var limit	= 24;
			for (var a=6;a>=1;a--) {
				for(var b in ar_now[a]) {
					var txt	= '<div class="square active_square medal fl_l level_{LEVEL}_1 medal_{ID}" title="" onclick="GLOBAL.honor.showMedal(\'{ID}\',\'{LEVEL}\')" onmouseover="TOOLTIP.show(this,{\'type\':\'medals\',\'tooltip_id\':\'medal_{LEVEL}_{ID}\'});"></div>'.format({'LEVEL':a,'ID':ar_now[a][b]});
					ar_all_medals.push(txt);
				}
			}

			/** дополняем пустыми полями */
			for (var a = count(ar_all_medals); a<=limit;a++) {
				var txt	= '<div class="square active_square fl_l pointer"></div>';
				ar_all_medals.push(txt);
			}

			return ar_all_medals;
		}
		
		/** HTML массив с орденами */
		function _getOrdensHtml(ar_now) {
			var ar_all_ordens	= [];
			var limit	= 24;

			for(var b in ar_now) {
				var txt	= '<div class="square active_square medal fl_l orden orden_{ID}" title="" onclick="GLOBAL.honor.showOrden(\'{ID}\')" onmouseover="TOOLTIP.show(this,{\'type\':\'ordens\',\'tooltip_id\':\'orden_{ID}\'});"></div>'.format({'ID':ar_now[b]});
				ar_all_ordens.push(txt);
			}

			/** дополняем пустыми полями */
			for (var a = count(ar_all_ordens); a<=limit;a++) {
				var txt	= '<div class="square active_square fl_l pointer"></div>';
				ar_all_ordens.push(txt);
			}

			return ar_all_ordens;
		}
			
		return t;
	}
	
	t.booster	= boosterHandler(t);
	function boosterHandler(self) {
		var t	= {
			'self'	: self,
			'path'	: {
				'tab_all'	: '#path_booster_tab_all .path_list',
				'tab_1'		: '#booster_list_1',
				'tab_2'		: '#booster_list_2',
				'tab_btn_all'	: '#path_booster_tabs .btn'
			}
		}
		
		/** веш в котором храним все данные для игрока */
		var _cache	= {};
		
		/** обработчик специализаций */
		t.spec	= specHandler(t);
		function specHandler(self) {
			var t	= {
				'self'	: self
			}
			
			/** */
			t.screenMain	= function() {
				var ok	= function(r) {
					
					/**
					 * spec_info вида:
						[422] => Array
							(
							[id] => 422
							[level_1] => 0
							[level_2] => 0
							[level_3] => 0
							[level_1_rented] => 0
							[level_2_rented] => 0
							[level_3_rented] => 0
							[rent_to] => 0
							[level_1_can] => 0
							[level_2_can] => 0
							[level_3_can] => 0
							[level_1_rent] => 0
							[level_2_rent] => 0
							[level_3_rent] => 0
							[level_1_class] => 1
							[level_2_class] => 0
							[level_3_class] => 0
							[level_1_blur] => 1
							[level_2_blur] => 0
							[level_3_blur] => 0
						);
					**/
				       
					PLAYER.cache.set(LOCAL_CACHE_USER_SPEC,r);
					var vars	= {
						vars	: {
							'rating_info'	: r.rating_info,
							'spec_info'	: r.spec_info,
							'other'		: r.other_info
						}
					}
					var txt = SKIN.parse('actions/spec/spec_main',vars)
					$(t.self.path.tab_1).html(txt);
				}
				
				API.call('spec.getInfo',{},ok);
			}
			
			/** вклчюить \ отлючить автоаренду */
			t.swithAutoRent	= function(spec_id,level) {
				var ok	= function(r) {
					bOk(g('location.spec_auto_rent_res_'+r.value));
					t.screenMain();
					lPopupRemove();
				}
				
				var data = {
					spec_id		: spec_id,
					level		: level,
					auto_rent	: $('#spec_auto_rent:checked').val()
				}
				
				API.call('spec.setAutoRent',data,ok,t.error);
			}
			
			/** пробуем взять */
			t.doAdd		= function(spec_id,level) {
				var ok	= function(r) {
					var txt	= g('location.spec_add_ok').format({SPEC_NAME:g('hint.spec_'+spec_id)})
					bOk(txt);
					t.screenMain();
				}
				
				API.call('spec.doAdd',{'spec_id':spec_id,'level':level},ok,t.error);
			}
			
			/** аренда  - показ окна */
			t.rentPopup	= function(spec_id,level,popup_type) {
				popup_type	= popup_type || 1;
				var info	= PLAYER.cache.get(LOCAL_CACHE_USER_SPEC);
				var spec	= info.spec_info[spec_id];
				
				/** получаем порследню арендованую специализацию */
				var	last_level	= level;
				//log(spec);
				//log(spec_info);
				for(var a=1;a<=3;a++) {
					if (spec['isrent_'+a]==1 && a>level)
						last_level	= a;
				}
				
				var vars	= {
					vars	: {
						'level'		: last_level,
						'spec_id'	: spec_id,
						'amount'	: info.other_info.price_rent[last_level],
						'auto_rent'	: spec['auto_rent'],
						'popup_type'	: popup_type /** 1 - обычный, 2 переклчюение типа аренды */
					}
				}
				
				var txt	= SKIN.parse('actions/spec/spec_popup',vars);
				var p	= popup();

				p.add({
					'message'	: txt,
					'title'		: 'Аренда специализации',
					'simple'	: true,
					'width'		: 350
				}).show();
			}
			
			/** арендуем - вызов из  popup  */
			t.doRent	= function(spec_id,level)  {
				var ok	= function(r) {
					var txt	= g('location.spec_rent_ok').format({SPEC_NAME:g('hint.spec_'+spec_id)});
					bOk(txt);
					t.screenMain();
					lPopupRemove();
				}
				
				var data = {
					spec_id		: spec_id,
					level		: level,
					auto_rent	: $('#spec_auto_rent:checked').val()
				}
				
				API.call('spec.doRent',data,ok,t.error);
			}
			
			/** сбросить спциализации */
			t.reset		= function() {
				var data	= {
					'price_type'	: SKIN.price.getSelected('#spec_select_price')
				}
				
				var ok	= function(r) {
					bOk(g('location.spec_reset_ok'));
					t.screenMain();
				}
				
				API.call('spec.reset',data,ok,t.error);
			}
			
			/** */
			t.error		= function(r) {
				if (r.code==10) {
					noMoney();
					return;
				}
				bAlert(g('error.spec_'+r.code));
			}
			
			return t;
		}
		
		t.blot	= blotHandler(t);
		function blotHandler(self) {
			var t	= {
				'self'	: self,
				path	: {
					'amount_stat'	: '#path_blot_result_money'
				}
			}
			
			var _cache	= {
				'active'	: {},	// массив активных элементов
				'price'		: {}
			}
			
			/** */
			t.screenMain	= function() {
				_cache.active	= {};
				
				if (!MODULE_BLOT){
					return false;
				}
				
				var ok	= function(r) {
					_cache.price	= r.price;
					var vars	= {
						vars	: {
							price	: r.price,
							list	: r.list
						}
					}
					var txt = SKIN.parse('actions/blot/blot_main',vars)
					$(t.self.path.tab_2).html(txt);
				}
				
				API.call('blot.getInfo',{},ok);
			}
			
			/** усилить характеристики */
			t.addBooster	= function() {
				var need	= {};
				for (var i in _cache.active) {
					if (_cache.active[i] != true)
						continue;
					
					need[i]	= 1;
				}
				
				/** */
				API.call('blot.addBooster',{'need':need},function(){
					bOk(g('location.blot_spend_ok'));
					ACTIONS.booster.showGroup(2);
				},t.error);
			}
			
			/** покупка скидки */
			t.addDiscount	= function(discount_id) {
				/** */
				API.call('blot.addDiscount',{'discount_id':discount_id},function(){
					bOk(g('location.blot_spend_ok'));
					ACTIONS.booster.showGroup(2);
				},t.error);
			}
			
			/** кликнукли по характеристики - заносим в массив - увеличиваем стоимость */
			t.clickStat	= function(key) {
				log(key);
				if (typeof _cache.active[key]=='undefined') {
					_cache.active[key]	= true;
				} else {
					_cache.active[key]	= !_cache.active[key];
				}
				
				/** пересчитываем цену */
				var amount	= 0;
				for (var i in _cache.active) {
					if (_cache.active[i] != true)
						continue;
					
					var t	= _cache.price.booster[i];
					amount	= amount + t;
				}
				
				$(this.path.amount_stat).html(amount);
			}
			
			/** проверить пост - его наличие */
			t.checkPost	= function(post_id) {
				SOCIAL.info.checkPost(post_id,function(res){
					API.call('blot.statBlotOk',{'res':res,post_id:post_id});
				});
			}
			
			/** */
			t.error		= function(r) {
				if (r.code==10) {
					noMoney();
					return;
				}
				bAlert(g('error.blot_'+r.code));
			}
			
			return t;
		}
		
		/** главный экран усилителей */
		t.screenMain	= function(group_id) {
			
			if (MODULE_BLOT && !MODULE_SPEC) {
				group_id	= 2;
			} else {
				group_id	= group_id || PLAYER.tab.get(TAB_BOOSTER,1);
			}
			
			var vars	= {
				vars	: {
					
				}
			};
			SKIN.main(SKIN.parse('/actions/booster/booster_main',vars));
			t.showGroup(group_id);
		}
		
		/** переклчюаем группу */
		t.showGroup	= function(num) {
			PLAYER.tab.set(TAB_BOOSTER,num);
			if (num == 1)
				this.spec.screenMain();
			else if (num == 2)
				this.blot.screenMain();
			
			/** */
			$(this.path.tab_all).addClass('hidden');
			$(this.path['tab_'+num]).removeClass('hidden');
			
			$(this.path.tab_btn_all).removeClass('selected');
			$(this.path.tab_btn_all + '[rel='+num+']').addClass('selected');
		}
		
		return t;
	}
	
	t.smith		= smithHandler(t);
	function smithHandler(self){
		var t	= {
			'self'	: self,
			'path'	: {
				
			}
		}
		
		/** веш в котором храним все данные для игрока */
		var _cache	= {};
		
		/** мастер кузнечь */
		t.master	= masterHandler(t);
		function masterHandler(self) {
			var t	= {
				'self'	: self
			}
			
			/** главная страница мастера кузнеча */
			t.screenMain	= function() {
				
				var ok	= function(r) {
					var vars	= {
						vars	: {
							'list'	: r.list
						}
					}
					SKIN.main(SKIN.parse('actions/smith/smith_master_main',vars),SCREEN_SMITH_MASTER);	
				}
				
				API.call('smith.getMasterList',{},ok);
			}
			
			/** попап с инфой для конкретного предмета */
			t.getInfo	= function(index) {
				var ok	= function(r) {
					var vars = {
						vars	: {
							info	: r.info
						}
					}
					
					SKIN.popupShow(SKIN.parse('actions/smith/smith_master_popup',vars));
				}
				
				API.call('smith.getMasterInfo',{'index':index},ok,t.self.error);
			}
			
			/** ковать */
			t.doWork	= function(index,level) {
				var ok	= function(r) {
					bOk(g('location.smith_master_work_ok'));
					
					if (typeof r.next != 'undefined' && r.next == 1) {
						//log('next');
						ACTIONS.smith.master.getInfo(index);
						return;
					} else {
						SKIN.popupClose();
					}
				}
				
				/* */
				var er	= function(r) {
					if (r.code == 5)
						return ACTIONS.smith.master.getInfo(index);
					
					return t.self.error(r);
				}
				
				var price_type	= SKIN.price.getSelected();
				API.call('smith.doWorkMaster',{index:index,price_type:price_type,level:level},ok,er);
			}
			
			return t;
		}
		
		t.error		= function(r) {
			if (r.code == 10)
				return noMoney();
			
			
			
			bAlert(g('error.smith_'+r.code));
		}
		
		return t;
	}
	
	/** подземелье */
	t.dungeon		= dungeonHandler(t);
	function dungeonHandler(self) {
		var t	= {};
		t.self	= self;
		
		t.screenMain		= function() {
			SKIN.main(SKIN.parse('dungeon/dungeon_main'));
		}
		
		t.screenFight		= function() {
			SKIN.main(SKIN.parse('dungeon/dungeon_fight'));
		}
		
		return t;
	}
	
	/** зверушки */
	t.pet		= petHandler(t);
	function petHandler(self) {
		var t	= {};
		t.self	= self;
		
		var _cache	= {
			shaman	: {
				price	: {},
				list	: {}
			}
		}
		
		/** */
		t.screenMain		= function() {
			if (!MODULE_PET) {
				return false;
			}
			
			var ok	= function(r) {
				
				var vars	= {
					vars	: {
						'buy_list'	: r.buy_list,
						'cage'		: r.cage,
						'list'		: r.list,
						'info'		: r.info
					}
				}
				
				
				_cache.shaman.price	= clone(r.list.price_shaman);
				SKIN.main(SKIN.parse('actions/pet/pet_main',vars),SCREEN_PET);
			}
			
			API.call('pet.getInfo',{},ok);
		}
		
		/** посадить в клетку */
		t.cageOn		= function() {
			var ok	= function() {
				bOk(g('location.pet_cageon'));
				if (SKIN.nowScreen() == SCREEN_PET)
					ACTIONS.pet.screenMain();
				else 
					SKIN.profile.reloadPet();
			}
			API.call('pet.cageOn',{},ok,t.error);
		}
		
		/** посадить в клетку */
		t.cageOff		= function() {
			var ok	= function() {
				bOk(g('location.pet_cageoff'));
				if (SKIN.nowScreen() == SCREEN_PET)
					ACTIONS.pet.screenMain();
				else 
					SKIN.profile.reloadPet();
			}
			API.call('pet.cageOff',{},ok,t.error);
		}
		
		/** показываем детальную информацию о зверушке а также можем ее сразу купить*/
		t.screenAbout		= function(type) {
			var ok	= function(r) {
				log(r);
				
				var vars	= {
					vars	: {
						'info'	: r.info
					}
				}
				
				SKIN.main(SKIN.parse('actions/pet/pet_about',vars),SCREEN_PET);
			}
			
			API.call('pet.getAbout',{type:type},ok,t.error);
		}
		
		/** покупаем зверушку */
		t.buy			= function(type) {
			var ok	= function(r) {
				PLAYER.tab.set(TAB_PET,1);
//				SKIN.setAfterShow(function(){
					bOk(g('location.pet_buy_ok'));
//				});
				ACTIONS.pet.screenMain();
			}
			
			var price_type	= SKIN.price.getSelected('#path_pet_price');
			API.call('pet.buy',{type:type,price_type:price_type},ok,t.error);
		}
		
		/** взять в бой */
		t.doTake		= function(pet_id) {
			var ok		= function(r) {
				ACTIONS.pet.screenMain();
				bOk(g('location.pet_take_ok'));
			}
			
			var price_type	= SKIN.price.getSelected('#path_pet_id_'+pet_id,pet_id);
			API.call('pet.doTake',{price_type:price_type,pet_id:pet_id},ok,t.error);
		}
		
		/** тренировать текущю зверушку */
		t.trainingInfo		= function() {
			var ok		= function(r) {
				var vars	= {
					vars	: r
				}
				
				var txt	= SKIN.parse('actions/pet/pet_training_alert',vars);
				var p	= popup();

				p.add({
					'message'	: txt,
					'title'		: 'Тренировать',
					'width'		: 536,
					'simple'	: true
				}).show();
				
				GLOBAL.set(ON_CLOSE_L_POPUP,function(){
					ACTIONS.pet.screenMain();
				});
			}
			
			API.call('pet.trainingInfo',{},ok,t.error);
		}
		
		/** тренируем  */
		t.doTraining		= function(next_level) {
			var ok	= function(r) {
				bOk(g('location.pet_training_ok'));
				ACTIONS.pet.trainingInfo();
			}
			
			var price_type	= SKIN.price.getSelected('#path_price_training','price_training');
			API.call('pet.doTraining',{price_type:price_type,next_level:next_level},ok,t.error);
		}
		
		/** */
		t.upgradeCage		= function() {
			var price_type	= SKIN.price.getSelected('#path_cage_price');
			var ok		= function(r) {
				bOk(g('location.pet_cage_upgrade_ok'));
				if (SKIN.nowScreen() == SCREEN_PET)
					ACTIONS.pet.screenMain();
			}
			
			API.call('pet.upgradeCage',{price_type:price_type},ok,t.error);
		}
		
		/** */
		t.screenFight		= function() {
			SKIN.main(SKIN.parse('dungeon/dungeon_fight'));
		}
		
		/** экран лечения зверей */
		t.screenHeal		= function() {
			alert('ACTIONS.pet.screenHeal();');
		}
		
		/** когда двигаем ползунок */
		t.shaman		= function(value,pet_id) {
			_cache.shaman.list[pet_id]	= value;
			
			var price	= {};
			for (var i in _cache.shaman.price) {
				price[i]	= {};
				for (var b in _cache.shaman.price[i]) {
					price[i][b]	= ceil(_cache.shaman.price[i][b] * value);
				}
			}
			$('#path_percent_'+pet_id).html(value);
			$('#path_shaman_price_'+pet_id).html(SKIN.price.getBlock(price,'pet_price_'+pet_id,function(price_type){
				if (price_type == 'type2') 
					$('#path_time_'+pet_id).html('до 48 часов');
				else
					$('#path_time_'+pet_id).html('1 минуту');
			}));
		}
		
		/** пробуем воскресить */
		t.doShaman		= function(pet_id) {
			var data	= {
				chance		: _cache.shaman.list[pet_id],
				pet_id		: pet_id,
				price_type	: SKIN.price.getSelected('#path_pet_id_'+pet_id,'pet_price_'+pet_id)
			}
			
			/** */
			var ok		= function(r) {
				ACTIONS.pet.screenMain();
				bOk(g('location.pet_doshaman_ok'));
			}
			
			API.call('pet.doShaman',data,ok,t.error);
		}
		
		/** узнать результат */
		t.shamanResult		= function(pet_id) {
			var data	= {
				pet_id		: pet_id
			}
			
			/** */
			var ok		= function(r) {
				ACTIONS.pet.screenMain();
				if (r.result == 1)
					bOk(g('location.pet_shaman_result_1'));
				else
					bAlert(g('location.pet_shaman_result_0'));
			}
			
			API.call('pet.shamanResult',data,ok,t.error);
		}
		
		/** переименовать */
		t.renameInfo		= function() {
			var txt	= SKIN.parse('actions/pet/pet_rename_alert');
			var p	= popup();

			p.add({
				'message'	: txt,
				'title'		: 'Переименовать',
				'width'		: 320,
				'simple'	: true
			}).show();
		}
		
		/** */
		t.doRename		= function() {
			var ok	= function(r) {
				ACTIONS.pet.screenMain();
				bOk(g('location.pet_rename_ok'));
			}
			
			API.call('pet.doRename',{'name':$('#path_pet_rename').val()},ok,t.error);
		}
		
		/** экран бутылочек - 3 бутылки */
		t.screenHeal		= function() {
			var ok	= function(r) {
				var vars	= {
					vars	: {
						price	: {
							'item_130'	: SKIN.price.getBlock(r.list['item_130'].price,'item_130'),
							'item_131'	: SKIN.price.getBlock(r.list['item_131'].price,'item_131'),
							'item_132'	: SKIN.price.getBlock(r.list['item_132'].price,'item_132')
						}
					}
				}
				
				//log(vars);
				
				var txt	= SKIN.parse('actions/pet/pet_heal_alert',vars);
				var p	= popup();

				p.add({
					'message'	: txt,
					'title'		: 'Зелья зверушки',
					'simple'	: true,
					'width'		: 400
				}).show();
			}
			
			API.call('shop.getPetPriceHeal',{},ok);
		}
		
		/** купить бутылочку */
		t.addPotion		= function(id,max) {
			var data = {
				'price_type'	: SKIN.price.getSelected('#price_block_potion_'+id,'item_'+id),
				'id'		: id,
				'type'		: 'items',
				'max'		: typeof max == 'undefined' ? false : max
			}

			var th	= this;
			API.call('shop.buy',data,function(r){
				ACTIONS.pet.screenHeal();
				bOk(g('global.potion_buy_ok'));
			},function(r){
				if (r.code == 10)
					return noMoney();
				bAlert(g('error.shop_'+r.code));
			});
		}
		
		/** выпить бутылочку - лечебные + оборотку */
		t.usePotion		= function(item_id) {
			var ok		= function(r) {
				bOk(r.message);
				SKIN.profile.reloadPet();
				ACTIONS.pet.screenHeal();
			}
			
			API.call('pet.usePotion',{'item_id':item_id},ok,t.error);
		}
		
		/** отказаться от компенсации */
		t.noRefund		= function() {
			var ok	= function() {
				ACTIONS.pet.screenMain();
			}
			API.call('pet.noRefund',{},ok,t.error);
		}
		
		/** получить компенсацию */
		t.doRefund		= function() {
			var ok	= function() {
				ACTIONS.pet.screenMain();
			}
			API.call('pet.doRefund',{},ok,t.error);
		}
		
		/** */
		t.error			= function(r) {
			if (r.code == 10)
				return noMoney();

			if (r.code == 48)
				return ACTIONS.pet.trainingInfo();
			bAlert(g('error.pet_'+r.code));
		}
		
		return t;
	}
	
	/** штаб */
	t.schtab	= schtabHandler(t);
	function schtabHandler(self) {
		var t	= {};
		t.self	= self;
		
		var _cache	= {
			fight_list	: {}	// список нападений
		}
		
		/** штаб */
		t.screenMain		= function() {
			var ok		= function(r) {
				var vars	= {
					vars	: r
				}
				
				for (var i in r.schtab_list) {
					var fight_info	= r.schtab_list[i];
					_cache.fight_list[fight_info.enemy_id] = fight_info;
				}
				
				SKIN.main(SKIN.parse('actions/schtab/schtab_main',vars),SCREEN_SCHTAB);
			}
			
			API.call('schtab.getInfo',{},ok);
		}
		
		/** возвращает информацию о бое */
		t.getFightInfo		= function(enemy_id) {
			if (typeof _cache.fight_list[enemy_id] != 'undefined') {
				return  _cache.fight_list[enemy_id];
			}
			
			return false;
		}
		
		/** сохранить конфигурацию */
		t.doAutolistConf	= function() {
			var ok		= function() {
				bOk(g('location.schtab_autolist_ok'));
			}
			
			var data	= {
				'add_money1'	: $('#path_autolist_add_money1').val(),
				'add_money2'	: $('#path_autolist_add_money2').val(),
				'del_money1'	: $('#path_autolist_del_money1').val()
			};
			
			API.call('schtab.doAutolistConf',data,ok,t.error);
		}
		
		/** */
		t.addRobList		= function(type,enemy_id) {
			var data	= {
				type		: type,
				enemy_id	: enemy_id
			};
			
			var ok		= function() {
				bOk(g('location.schtab_add_rob_list_ok'));
			}
			
			API.call('schtab.addRobList',data,ok,t.error);
		}
		
		/** */
		t.deleteFromRobList	= function(type,enemy_id) {
			var data	= {
				type		: type,
				enemy_id	: enemy_id
			};
			
			var ok		= function() {
				bOk(g('location.schtab_del_rob_list_ok'));
			}
			
			API.call('schtab.deleteFromRobList',data,ok,t.error);
		}
		
		/** */
		t.error			= function(r) {
			bAlert(g('error.schtab_'+r.code));
		}
		
		return t;
	}
	
	/** */
	t.test		= testHandler(t);
	function testHandler(self) {
		var t	= {};
		t.self	= self;
		
		/** используется на тестовых серверах */
		t.screenMain		= function() {
			SKIN.main(SKIN.parse('actions/test/test_main'));
		}
		
		t.screenDemoPopup	= function() {
			SKIN.main(SKIN.parse('test/demopopup'));
		}
		
		t.screenTest		= function() {
			SKIN.main(SKIN.parse('test/test'));
		}
		
		t.screenTestTimers	= function() {
			SKIN.main(SKIN.parse('test/test_timers'));
		}
		
		t.screenTestSmith	= function() {
			SKIN.main(SKIN.parse('test/test_smith'));
		}
		
		t.screenTestSmithWork	= function() {
			SKIN.popupShow(SKIN.parse('test/test_smith_work'));
		}
		
		t.screenTestSmithSplit	= function() {
			SKIN.main(SKIN.parse('test/test_smith_split'));
		}
		
		t.screenDemoTooltip	= function() {
			SKIN.main(SKIN.parse('profile/demo_tooltip_items'));
		}
		
		t.screenChat		= function() {
			SKIN.main(SKIN.parse('test/test_chat'));
		}
		
		t.screenPost		= function() {
			SKIN.main(SKIN.parse('test/test_post'));
		}
		
		t.screenPandora		= function() {
			SKIN.main(SKIN.parse('test/test_pandora'));
		}
		
		t.screenFortress	= function() {
			SKIN.main(SKIN.parse('test/test_fortress'));
		}
		
		t.screenPeaceful	= function() {
			SKIN.main(SKIN.parse('test/test_peaceful'));
		}
		
		t.screenGuards		= function() {
			SKIN.main(SKIN.parse('test/test_guards'));
		}
		
		t.screenBandits		= function() {
			SKIN.main(SKIN.parse('test/test_bandits'));
		}
		
		t.screenFear		= function() {
			SKIN.main(SKIN.parse('test/test_fear'));
		}
		
		t.screenFearAbout	= function() {
			SKIN.main(SKIN.parse('test/test_fear_about'));
		}
		
		t.screenFearRating	= function() {
			SKIN.main(SKIN.parse('test/test_fear_rating'));
		}
		
		t.screenFearArmory	= function() {
			SKIN.popupShow(SKIN.parse('test/test_fear_armory'));
		}
		
		t.screenFearRoom	= function() {
			SKIN.main(SKIN.parse('test/test_fear_room'));
		}
		
		t.screenStamps	= function() {
			/** пример конфига, который будет идти с сервера */
			var vars = {
				1 : mt_rand(0,5),// id коллекции и номер марки от 1 до 5
				2 : mt_rand(0,5),
				3 : mt_rand(0,5),
				4 : mt_rand(0,5),
				5 : mt_rand(0,5),
				6 : mt_rand(0,5),
				7 : mt_rand(0,5),
				8 : mt_rand(0,5),
				9 : mt_rand(0,5),
				10 : mt_rand(0,5),
				11 : mt_rand(0,5),
				12 : mt_rand(0,5),
				13 : mt_rand(0,5),
				14 : mt_rand(0,5),
				15 : mt_rand(0,5),
				16 : mt_rand(0,5),
				17 : mt_rand(0,5),
				18 : mt_rand(0,5),
				19 : mt_rand(0,5),
				20 : mt_rand(0,5),
				21 : mt_rand(0,5),
				22 : mt_rand(0,5),
				23 : mt_rand(0,5),
				24 : mt_rand(0,5),
				25 : mt_rand(0,5),
				26 : mt_rand(0,5),
				27 : mt_rand(0,5),
				28 : mt_rand(0,5),
				29 : mt_rand(0,5),
				30 : mt_rand(0,5),
				31 : mt_rand(0,5),
				32 : mt_rand(0,5),
				33 : mt_rand(0,5),
				34 : mt_rand(0,5),
				41 : mt_rand(0,5),
				42 : mt_rand(0,5),
				43 : mt_rand(0,5),
				44 : mt_rand(0,5),
				45 : mt_rand(0,5),
				46 : mt_rand(0,5),
				47 : mt_rand(0,5),
				48 : mt_rand(0,5),
				49 : mt_rand(0,5),
				50 : mt_rand(0,5),
				51 : mt_rand(0,5),
				52 : mt_rand(0,5),
				53 : mt_rand(0,5),
				54 : mt_rand(0,5),
				55 : mt_rand(0,5),
				56 : mt_rand(0,5),
				57 : mt_rand(0,5),
				58 : mt_rand(0,5),
				59 : mt_rand(0,5)
			};
			
			SKIN.main(SKIN.parse('test/test_stamps', {'vars':vars}));
		}
		
		t.screenStampsPopup	= function(collection, number) {
			var vars = {
				'name'	: collection,
				'number': number
			};
			
			var txt	= SKIN.parse('test/test_stamps_popup', {'vars':vars});
			var p	= popup();

			p.add({
				'message'	: txt,
				'title'		: 'Купить марку',
				'simple'	: true,
				'width'		: 300
			}).show();
		}
		
		t.endAllTutor		= function() {
			for (var i = 0;i<JS_TUTORIAL_ALL;i++) {
				setSettings('tut_begin_step'+i,1);
			}
		}
		return t;
	}
	
	/** */
	t.okapi		= okapiHandler(t);
	function okapiHandler(self) {
		var t	= {};
		t.self	= self;
		
		t.users	= usersHandler(t);
		function usersHandler(self) {
			var t	= {};
			t.self	= self;
			
			/** получить информцию о пользователях */
			t.getInfo	= function() {
				API.call('ok.usersGetInfo',{data:GLOBAL.data});
			}
			
			return t;
		}
		
		t.uploadTest	= function() {
			GLOBAL.set(GLOBAL_GET_FAPI_CONFIRM,function() {
					API.call('ok.uploadTest',{data:GLOBAL.data});
				});
			FAPI.UI.showPermissions("['PHOTO CONTENT']");
		}
			
		/** публикуем у себя в ленте всякую фигню */
		t.publicToMe	= function(resig) {
			var ok	= function(r) {
				GLOBAL.set(GLOBAL_GET_FAPI_CONFIRM,function(resig) {
					API.call('ok.publicToMe',{data:GLOBAL.data,resig:resig});
				});
				FAPI.UI.showConfirmation('stream.publish',r.message,r.sig);
			}

			API.call('ok.getSigPublicToMe',{data:GLOBAL.data},ok);
		}
		
		return t;
	}
	
	/** */
	t.mirapi		= okapiHandler(t);
	function okapiHandler(self) {
		var t	= {};
		t.self	= self;
		
		/** получить информцию о пользователях */
		t.getMyInfo	= function() {
			API.call('mir.usersGetInfo',{data:GLOBAL.data});
		}
		
		/** получить информцию о пользователях */
		t.getMyInfo	= function() {
			API.call('mir.usersGetInfo',{data:GLOBAL.data});
		}
		
		t.uploadTest	= function() {
			GLOBAL.set(GLOBAL_GET_FAPI_CONFIRM,function() {
					API.call('ok.uploadTest',{data:GLOBAL.data});
				});
			FAPI.UI.showPermissions("['PHOTO CONTENT']");
		}
			
		/** публикуем у себя в ленте всякую фигню */
		t.publicToMe	= function(resig) {
			var ok	= function(r) {
				GLOBAL.set(GLOBAL_GET_FAPI_CONFIRM,function(resig) {
					API.call('ok.publicToMe',{data:GLOBAL.data,resig:resig});
				});
				FAPI.UI.showConfirmation('stream.publish',r.message,r.sig);
			}

			API.call('ok.getSigPublicToMe',{data:GLOBAL.data},ok);
		}
		
		return t;
	}
	
	/** */
	t.swag		= swagHandler(t);
	function swagHandler(self) {
		var t	= {};
		t.self	= self;
		
		/** арендуем котомку */
		t.doBuy		= function(size) {
			var ok	= function(r) {
				ACTIONS.profile.screenMain();
			}
			
			var data = {
				'size'		: size,
				'price_type'	: SKIN.price.getSelected('#path_swag_price_'+size,'price_'+size)
			}
			
			API.call('swag.doBuy',data,ok,t.error);
		}
		
		/** увеличиваем котомку */
		t.doBig		= function(size) {
			var ok	= function(r) {
				ACTIONS.profile.screenMain();
			}
			
			var data = {
				'size'		: size,
				'price_type'	: SKIN.price.getSelected('#path_swag_price_extra_'+size,'price_extra_'+size)
			}
			
			API.call('swag.doBig',data,ok,t.error);
		}
		
		/** увеличиваем котомку */
		t.doReturn	= function() {
			var ok	= function(r) {
				ACTIONS.profile.screenMain();
			}
			
			var data = {
				'price_type'	: SKIN.price.getSelected('#path_swag_price_return','price_return')
			}
			
			API.call('swag.doReturn',data,ok,t.error);
		}
		
		/** */
		t.error			= function(r) {
			if (r.code == 10)
				return noMoney();
			bAlert(g('error.swag_'+r.code));
		}
		
		return t;
	}
	
	/** кликнули по иконки wiki - показываем справку */
	t.showWiki	= function(wiki_id) {
		/** по идее:
		 *1. грузим шаблон с wiki 
		 *2. Отдаем в skin - выводим все на экране.
		 **/
		alert(wiki_id);
	}

	/** при первой инициализации */
	t.start		= function(show_default) {
		show_default		= show_default || function(){ACTIONS.profile.screenMain();}
		
		/** GLOBAL.auth - бывают данные когда мы смотрим чужого персонажа */
		var auth	= typeof GLOBAL.auth != 'undefined' ? GLOBAL.auth : GLOBAL.data;
		var data_auth	= auth; //GLOBAL.data;
		var data	= {
			'data'	: data_auth,
			'ip'	: GLOBAL.ip
		}
		
		/** добавляем подпись */
		if (typeof GLOBAL.auth != 'undefined') {
			data['auth_type']	= 1;
//			data['real_id']		= GLOBAL.data.viewer_id;
//			data['real_key']	= GLOBAL.data.auth_key;
			
			data['real_data']	= GLOBAL.data;
			data.data		= GLOBAL.auth;
			
			log(data);
		}
		
		var error	= function(response) {
			if (response.code == '3') {
				ACTIONS.profile.screenRegister();
			} else {
				alert('ACTIONS.start: Cant connect to server');
			}
		}
		
		/** устанавливаем ЯВНЫЕ данные окружения \ НЕ ЯВНЫЕ передались через API.actions*/
		var ok		= function(response) {
			/** проверяем друзей - кто в игре - получаем список - отправляем */
			ACTIONS.profile.updateFriendInGame();
			ACTIONS.profile.updateSocialInfo();
			
			/** после показа контента */
			SKIN.set('after_show',function() {
				/** проверяем наставника */
				ACTIONS.profile.checkTeacher();
			})
			
			/** показываем экран по умолчанию из starter.tpl */
			show_default();
		}
		
		/** */
		API.dontCheckRedirect	= true;
		API.call('global.start',data,ok,error);
		
	}
	
	/** показать чужой профайл */
	t.showProfile	= function(user_id) {
		//log(user_id);
		
		ENEMY	= enemyHandler(user_id);
		ENEMY.profile.showMain();
		
		/** возращает false - чтобы не отработал тег <A></A>*/
		return false;
	}
	
	/** показать чужой клан */
	t.showClan	= function(clan_id) {
		ACTIONS.clan_enemy.show(clan_id);
	}
	
	return t;
}

/** 
 *-------------------------------------------------------------------   
 *                       Btn - все кнопки проекта
 *-------------------------------------------------------------------   
 **/
function btnHandler() {
	var t	= {};
	
	t.profile	= profileHandler(t);
	function profileHandler(self) {
		var t	= {};
		t.self	= self;
		
		/** в профайле кликнули на конпку тренировка  */
		t.showTraining	= function() {						
			ACTIONS.profile.training.showPopup();
		}									
		return t;
	}	

	/** клик вызывает окно  покупки */
	t.showBuy	= function() {						
		ACTIONS.popupBuy();
	}										
	
	/** кликнули по оверлею или крестику */
	t.closePopup	= function() {
		SKIN.popupClose();
	}
	
	return t;	
}

/** 
 *-------------------------------------------------------------------   
 *                       Player - обработчик текущего игрока
 *-------------------------------------------------------------------   
 **/
function playerHandler() {
	var t		= {};
	t.user_id	= 0;	// наш user_id \ устанавливается в API.updatekey - во время инициализации
	
	t.profile	= profileHandler(t);
	function profileHandler(self) {
		var t	= {};
		t.self	= self;
		
		/** локальный кеш профайла */
		var _cache	= {};
		
		t.set		= function(conf) {
			for(var i in conf) {
				_cache[i]	= conf[i];
			}
			
			USERJS.add(_cache);
			this.autoUpdate();
			PLAYER.work.checkTimers();
		}
		
		/** */
		t.getInfo	= function(key) {
			if (typeof key == 'undefined')
				return _cache;
			
			if (typeof _cache[key]!=='undefined')
				return _cache[key];
			
			return key;
		}
		
		/** после получения каких либо данных перерисовываем их на странице */
		t.autoUpdate	= function() {
			/** счетчик почты */
			var txt	= _cache['count_new_post'] > 0 ? _cache['count_new_post'] : '';
			$('#menu_post div').html(txt);
			
			/** опыт, уровень, здоровье */
			SKIN.profile.reloadLife();
		}
		
		/** true \ false */
		t.isLord	= function() {
			return this.getInfo('is_lord')
		}
		
		/** ссылка на мой профайл */
		t.getLink	= function() {
			return 'http://' + PLAYER.profile.getInfo('profile_url');
			return BOTVA_URL + 'id' + PLAYER.profile.getInfo('user_id');
		}
		
		return t;
	}
	
	t.money			= moneyHandler(t);
	function moneyHandler(self) {
		var t	= {};
		t.self	= self;
		
		/** локальный кеш денег */
		var _cache	= {};
		
		t.set		= function(conf) {
			for(var i in conf) {
				_cache[i]	= conf[i];
				$('#'+i).html(digit(conf[i]));
			}
		}
		
		/** */
		t.getInfo	= function(key) {
			if (typeof _cache[key]!=='undefined')
				return _cache[key];
			
			return key;
		}
		
		/** перерисовываем счетчики игрока */
		t.show		= function() {
			for (var i in _cache) {
				$('#'+i).html(degit(_cache[i]));
			}
		}
		
		return t;
	}
	
	t.house			= houseHandler(t);
	function houseHandler(self) {
		var t	= {};
		t.self	= self;
		
		/** локальный кеш денег */
		var _cache	= {};
		
		t.set		= function(conf) {
			for(var i in conf) {
				_cache[i]	= conf[i];
			}
		}
		
		/** */
		t.getInfo	= function(key) {
			if (typeof _cache[key]!=='undefined')
				return _cache[key];
			
			return key;
		}
		
		t.have		= function(key) {
			if (this.getInfo(key) > time() || this.getInfo(key) == 1)
				return true;
			
			return false;
		}
		
		return t;
	}
	
	t.specials		= specialsHandler(t);
	function specialsHandler(self) {
		var t	= {};
		t.self	= self;
		
		/** локальный кеш денег */
		var _cache	= {};
		
		t.set		= function(conf) {
			for(var i in conf) {
				_cache[i]	= conf[i];
			}
		}
		
		/** */
		t.getInfo	= function(key) {
			key	= key || 'all';
			
			if (key === 'all' || typeof key == 'undefined')
				return _cache;
			
			if (typeof _cache[key]!=='undefined')
				return _cache[key];
			
			return key;
		}
		
		t.have		= function(key) {
			if (this.getInfo(key) > 0)
				return true;
			
			return false;
		}
		
		return t;
	}
	
	t.gifts			= giftsHandler(t);
	function giftsHandler(self) {
		var t	= {};
		t.self	= self;
		var _cache	= {};	/** локальный кеш  */
		
		t.set			= function(conf) {
			for(var i in conf) {
				_cache[i]	= conf[i];
			}
		}
		
		/** */
		t.getInfo		= function(key) {
			if (typeof _cache[key]!=='undefined')
				return _cache[key];
			
			return key;
		}
		
		return t;
	}
	
	t.skills		= skillsHandler(t);
	function skillsHandler(self) {
		var t	= {};
		t.self	= self;
		
		t.set		= function(conf) {
			
		}
		
		return t;
	}
	
	t.items			= itemsHandler(t);
	function itemsHandler(self) {
		var t	= {};
		t.self	= self;
		var _cache	= {};
		
		t.clearAll	= function() {
			_cache	= {};
		}
		
		t.set		= function(conf) {
			for(var i in conf) {
				_cache[i]	= conf[i];
			}
		}
		
		/** вещи храняться в одевалке по их индексу */
		t.getInfo	= function(key) {
			if (typeof key == 'undefined')
				return _cache;
			
			if (typeof _cache[key]!=='undefined')
				return _cache[key];
			
			return key;
		}
		
		/** снять вещь */
		t.deActivate	= function(index) {
			var now_activate	= _cache[index].activated;
				
			var ok	= function(r) {
				SKIN.profile.reload();
				TOOLTIP.hide();
			}
			
			var error	= function(r) {
				_cache[index].activated	= now_activate;
				t.error(r);
			}
			
			_cache[index].activated	= 0;
			API.call('items.deActivate',{'index':index},ok,error);
		}
		
		/** надеть вещь */
		t.activate	= function(index) {
			var now_activate	= _cache[index].activated;
			
			var ok	= function(r) {
				SKIN.profile.reload();
				TOOLTIP.hide();
			}
			
			var error	= function(r) {
				_cache[index].activated	= now_activate;
				t.error(r);
			}
			
			_cache[index].activated	= 1;
			API.call('items.activate',{'index':index},ok,error);
		}
		
		/** если такая вещь по item_id */
		t.haveById	= function(item_id) {
			for (var index in _cache) {
				var item	= _cache[index];
				if (typeof item.item_id != 'undefined' && item.item_id == item_id)
					return true;
			}
		
			return false;
		}
		
		/** активирована ли вещь по индексу */
		t.isActivatedById = function(item_id) {
			for (var index in _cache) {
				var item	= _cache[index];
				if (typeof item.item_id != 'undefined' && item.item_id == item_id && item.activated == 1)
					return true;
			}
		
			return false;
		}
		
		/** выбросить */
		t.drop		= function(index) {
			var ok	= function(r) {
				PLAYER.items.clearAll();
				ACTIONS.profile.screenMain();
			}
			
			var th	= this;
			lConfirm({
				'message'	: g('confirm.item_drop_confirm'),
				'action'	: function() {
					API.call('items.drop',{'index':index},ok,th.error);
				}
			});
			
		}
		
		/** продать обратно */
		t.sell		= function(index) {
			var th	= this;
			var ok	= function(r) {
				lConfirmSell({
					'message'	: g('confirm.item_sell_confirm',{'AMOUNT':digits(r.amount)}),
					'action'	: function() {
						API.call('items.doSell',{'index':index},function(){
							PLAYER.items.clearAll();
							ACTIONS.profile.screenMain();
						},th.error);
					}
				})
			}
			
			API.call('items.getSellInfo',{'index':index},ok,this.error);
		}
		
		/** переложить в котомку */
		t.doSwag	= function(index) {
			var ok	= function(r) {
				SKIN.profile.reload();
				TOOLTIP.hide();
			}
			
			API.call('items.doSwag',{'index':index},ok,t.error);
		}
		
		/** переложить из котомки в одевалку */
		t.doUnSwag	= function(index) {
			var ok	= function(r) {
				SKIN.profile.reload();
				TOOLTIP.hide();
			}
			
			API.call('items.doUnSwag',{'index':index},ok,t.error);
		}
		
		/** общий обработчик ошибок */
		t.error		= function(r) {
			bAlert(g('error.items_'+r.code));
		}
		
		return t;
	}
	
	t.timers		= timersHandler(t);
	function timersHandler(self) {
		var t	= {};
		t.self	= self;
		
		t.set		= function(conf) {
			
		}
		
		/** */
		t.getTimerInfo	= function(type) {
			var ts = (new Date()).getTime() + 1*60*60*1000;
			var title	= 'Я свободен!';
			var script	= '\n\
$("#timer_'+type+'").countdown({\n\
	"timestamp"	: '+ts+',\n\
	"callback"	: function(days, hours, minutes, seconds){}\n\
});\n\
';
			var click	= '';
			script = '';
			
			if (type == 'work') {
				title = 'Я свободен!';
			} else if (type == 'fighting') {
				title = 'Пора в бой!';
			} else  {
				title = '00:10:25';
			}
			
		
			return {
				'title'		: title,
				'script'	: script,
				'click'		: click
			}
		}
		
		return t;
	}
	
	t.medals		= medalsHandler(t);
	function medalsHandler(self) {
		var t	= {};
		t.self	= self;
		
		/** локальный кеш  */
		var _cache	= {};
		
		t.set		= function(conf) {
			for(var i in conf) {
				_cache[i]	= conf[i];
				$('#'+i).html(digit(conf[i]));
			}
		}
		
		/** */
		t.getInfo	= function(key) {
			if (typeof key == 'undefined')
				return _cache;
			
			if (typeof _cache[key]!=='undefined')
				return _cache[key];
			
			return key;
		}
		
		return t;
	}
	
	t.ordens		= ordensHandler(t);
	function ordensHandler(self) {
		var t	= {};
		t.self	= self;
		
		/** локальный кеш  */
		var _cache	= {};
		
		t.set		= function(conf) {
			for(var i in conf) {
				_cache[i]	= conf[i];
				$('#'+i).html(digit(conf[i]));
			}
		}
		
		/** */
		t.getInfo	= function(key) {
			if (typeof key == 'undefined')
				return _cache;
			
			if (typeof _cache[key]!=='undefined')
				return _cache[key];
			
			return key;
		}
		
		return t;
	}
	
	t.stat			= statHandler(t);
	function statHandler(self) {
		var t	= {};
		t.self	= self;
		
		/** локальный кеш  */
		var _cache	= {};
		
		t.set		= function(conf) {
			for(var i in conf) {
				_cache[i]	= conf[i];
				$('#'+i).html(digit(conf[i]));
			}
		}
		
		/** */
		t.getInfo	= function(key) {
			if (typeof key == 'undefined')
				return _cache;
			
			if (typeof _cache[key]!=='undefined')
				return _cache[key];
			
			return key;
		}
		
		return t;
	}
	
	t.about			= aboutHandler(t);
	function aboutHandler(self) {
		var t	= {};
		t.self	= self;
		
		/** локальный кеш  */
		var _cache	= {};
		
		t.set		= function(conf) {
			for(var i in conf) {
				_cache[i]	= conf[i];
				$('#'+i).html(digit(conf[i]));
			}
		}
		
		/** */
		t.getInfo	= function(key) {
			if (typeof _cache[key]!=='undefined')
				return _cache[key];
			
			return key;
		}
		
		return t;
	}
	
	t.work			= workHandler(t);
	function workHandler(self) {
		var t	= {
			'path'	: {
				'fight'		: '#timer_fight',
				'fight_title'	: '#timer_fight_title',
				'fight_ico'	: '#timer_fight',
				'fight_id'	: '#timer_fight_title',
				
				'defence'	: '#timer_defence',
				'defence_title'	: '#timer_defence_title',
				'defence_ico'	: '#timer_defence',
				'defence_id'	: '#timer_defence_title'
			},
			'timeout'		: {
				'fightTimeout'	: 0
			}
		};
		t.self	= self;
		
		var _cache	= {};	/** локальный кеш  */
		
		var _data	= {
			'fight'		: function() {},
			'defence'	: function() {}
		};	
		
		t.set			= function(conf) {
			for(var i in conf) {
				_cache[i]	= conf[i];
			}
			
			this.checkTimers();
		}
		
		/** */
		t.getInfo		= function(key) {
			if (typeof _cache[key]!=='undefined')
				return _cache[key];
			
			return key;
		}
		
		/** после обновления работы - корректируем наши счетчики и логику кликов по ним */
		t.checkTimers		= function() {
			/** Время - если мы недавно нападали и сейчас пока перерыв между нападаениями  */
			var fight_timeout	= intval(PLAYER.profile.getInfo('last_attack')) + intval(PLAYER.cache.getInfo(JS_CACHE_RESTRICTION));
			
			if (_cache['work_end'] > time()) {
				_setFightWork();
			} else if (fight_timeout > time()){
				/** если мы недавно нападали и сейчас пока перерыв между нападаениями  */
				_setFightTimeout(fight_timeout);
				
			} else {
				_setFightDefault();
			}
			
			/** таймер защиты */
			if (PLAYER.profile.getInfo('defence_till') > time()) {
				_setDefenceWork();
			} else {
				_setDefenceDefault();
			}
			
		}
		
		/** кликнули по счетчику нападения \ работы */
		t.clickFight		= function() {
			_data.fight();
		}

		/** кликнули по счетчику защиты */
		t.clickDefence		= function() {
			_data.defence();
		}
		
		/** вызывается когда один из счетчиков работы завершил работу */
		t.checkEndWork		= function() {
			var handler	= hh(t);
			function hh(self) {
				var t	= {
					self	: self
				}
				
				/** пробуем завершить дозор */
				t.watch		= function() {
					var ok		= function(r) {
						if (SKIN.nowScreen() != SCREEN_WATCH)
							return;
						
						/** показываем на экране дозоре результат похода в дозор */
						ACTIONS.fight.screenWatch(false,r);
						return ;
					}
					
					var error	= function(r) {
						if (SKIN.nowScreen() != SCREEN_WATCH)
							return;
						
						if (r.code == 1) {
							/** уже нет работы - показываем бодалку */
							ACTIONS.fight.screenMain();
							return;
						}
						
						if (r.code == 2) {
							/** рано еще завершать работу */
							ACTIONS.fight.screenWatch();
							return ;
						}
					}
					
					API.call('profile.endWork',{'type':'watch'},ok,error);
				}
				
				/** пробуем завершить ферму */
				t.farm		= function() {
					var ok		= function(r) {
						if (SKIN.nowScreen() != SCREEN_FARM)
							return;
						
						/** на ферме не показываем призы - только шлем почту */
						ACTIONS.village.screenFarm();
						return ;
					}
					
					var error	= function(r) {
						if (SKIN.nowScreen() != SCREEN_FARM)
							return;
						
						if (r.code == 1) {
							/** уже нет работы - показываем бодалку */
							ACTIONS.village.screenFarm();
							return;
						}
						
						if (r.code == 2) {
							/** рано еще завершать работу */
							ACTIONS.village.screenFarm();
							return ;
						}
					}
					
					API.call('profile.endWork',{'type':'farm'},ok,error);
				}
				
				/** пробуем показываем экран с выборорм что дальше делать в шахте  */
				t.mineDig		= function() {
					var ok		= function(r) {
						if (SKIN.nowScreen() != SCREEN_MINE)
							return;
						
						/** 
						 * сюда также может придти из редиректа - когда завершилась работа. 
						 * Таким образом мы можем явно придти сюда, а можем попасть в screenChoice - через редирект из API
						 **/
						ACTIONS.mine.screenChoice();
						return ;
					}
					
					var error	= function(r) {
						if (SKIN.nowScreen() != SCREEN_MINE)
							return;
						
						if (r.code == 1) {
							/** уже нет работы - показываем шахту */
							ACTIONS.mine.screenMain();
							return;
						}
						
						if (r.code == 2) {
							/** рано еще завершать работу */
							ACTIONS.mine.screenWork();
							return ;
						}
					}
					
					API.call('profile.endWork',{},ok,error);
				}
				
				return t;
			}
			
			/** в завимости от типа текущей работы. Switch - нельзя использовать! */
			if (_cache.work_type == WORK_TYPE_WATCH) {
				handler.watch();
			} else if (_cache.work_type == WORK_TYPE_FARM) {
				handler.farm();
			} else if (_cache.work_type == WORK_TYPE_OPENING) {
				handler.mineDig();
			}
		}
		
		/** 
		 * -------------------------------------------------------------
		 *				PROTECTED
		 * -------------------------------------------------------------
		 **/
		
		/** устмнавливаем счетчик надаения в ноль - и клик на бодалку */
		function _setFightDefault() {
			$(t.path.fight_ico).removeClass('timer3 timer1 timer2').addClass('timer3');
			$(t.path.fight_title).html(g('global.timer_time_to_fight')).removeClass('countdownHolder');
			_data.fight	= function() {
				ACTIONS.fight.screenMain();
			}
		}
		
		/** устанавливаем счетчик защиты в ноль - и клик на бодалку */
		function _setDefenceDefault() {
			$(t.path.defence_ico).removeClass('timer3 timer1 timer2').addClass('timer2');
			$(t.path.defence_title).html(g('global.timer_time_to_defence')).removeClass('countdownHolder');
			_data.defence	= function() {
				ACTIONS.fight.screenMain();
			}
		}
		
		/** устанавливает счетчик в работу в зависимости от ее типа */
		function _setFightWork() {
			var handler	= workHandler(t);
			function workHandler(self) {
				/** 
				 *	модуль работает так: 
				 *	1 - в кажой типе работ, присваиваем в t.title \ t.click - значения
				 *	2 - вызываем функция _set - которая применяем данные для счетчиков на экране
				 **/
				var t	= {
					'self'	: self,
					'title'	: '',
					'click'	: function() {}
				};
				
				/** сейчас в дозоре */
				t.watch		= function() {
					$(t.self.path.fight_title).html('');
					var p	= {
						'time'	: PLAYER.work.getInfo('work_end'),
						'id'	: t.self.path.fight_id,
						'after'	: function(){
							PLAYER.work.checkEndWork();
						}
					}

					timer(p);
					$(t.self.path.fight_ico).removeClass('timer3 timer1 timer2').addClass('timer1');
					_data.fight	= function() {
						ACTIONS.fight.screenMain();
					}
					
				}

				/** сейчас на ферме */
				t.farm		= function() {
					$(t.self.path.fight_title).html('');
					var p	= {
						'time'	: PLAYER.work.getInfo('work_end'),
						'id'	: t.self.path.fight_id,
						'after'	: function(){
							PLAYER.work.checkEndWork();
						}
					}

					timer(p);
					$(t.self.path.fight_ico).removeClass('timer3 timer1 timer2').addClass('timer1');
					_data.fight	= function() {
						ACTIONS.village.screenFarm();
					}
				}
				
				/** сейчас в шахте копаем */
				t.mineDig		= function() {
					$(t.self.path.fight_title).html('');
					var p	= {
						'time'	: PLAYER.work.getInfo('work_end'),
						'id'	: t.self.path.fight_id,
						'after'	: function(){
							PLAYER.work.checkEndWork();
						}
					}

					timer(p);
					$(t.self.path.fight_ico).removeClass('timer3 timer1 timer2').addClass('timer1');
					_data.fight	= function() {
						ACTIONS.mine.screenMain();
					}
				}
				
				
				return t;
			}
			
			/** в завимости от типа текущей работы. Switch - нельзя использовать! */
			if (_cache.work_type == WORK_TYPE_WATCH) {
				handler.watch();
			}else if (_cache.work_type == WORK_TYPE_FARM) {
				handler.farm();
			}else if (_cache.work_type == WORK_TYPE_OPENING) {
				handler.mineDig();
			}
		}
		
		/** это не работа, а время ожидания до следюущего нападения. 5 или 15 минут */
		function _setFightTimeout(timeout) {
			$(t.path.fight_title).html('');
			var p	= {
				'time'	: timeout,
				'id'	: t.path.fight_id,
				'after'	: function(){
					clearTimeout(PLAYER.work.timeout.fightTimeout);
					PLAYER.work.timeout.fightTimeout	= setTimeout(function(){
						PLAYER.work.checkTimers();
					},1000);
				}
			}

			timer(p);
			$(t.path.fight_ico).removeClass('timer3 timer1 timer2').addClass('timer3');
			_data.fight	= function() {
				ACTIONS.fight.screenMain();
			}
		}
		
		function _setDefenceWork() {
			$(t.path.defence_title).html('');
			var p	= {
				'time'	: PLAYER.profile.getInfo('defence_till'),
				'id'	: t.path.defence_id,
				'after'	: function(){
					
				}
			}

			timer(p);
			$(t.path.defence_ico).removeClass('timer3 timer1 timer2').addClass('timer2');
			_data.defence	= function() {
				ACTIONS.fight.screenMain();
			}
		}
		return t;
	}
	
	t.clan			= clanHandler(t);
	function clanHandler(self) {
		var t	= {};
		t.self	= self;
		
		/** локальный кеш */
		var _cache	= {};
		
		t.set		= function(conf) {
			for(var i in conf) {
				_cache[i]	= conf[i];
			}
		}
		
		/** */
		t.getInfo	= function(key) {
			key	= key || 'all';
			
			if (key === 'all' || typeof key == 'undefined')
				return _cache;
			
			if (typeof _cache[key]!=='undefined')
				return _cache[key];
			
			return key;
		}
		
		/** текущий ранг пользователя */
		t.getRang	= function() {
			if (typeof _cache['users'] !== 'undefined' && typeof _cache['users'][PLAYER.profile.getInfo('user_id')] !== 'undefined' && typeof _cache['users'][PLAYER.profile.getInfo('user_id')]['rang'] !== 'undefined' )
				return typeof _cache['users'][PLAYER.profile.getInfo('user_id')]['rang'];
								
				return CLAN_USER_RANG_0;
		}
		
		/** поддерживает ли игрок данное действие */
		t.isAllow	= function(action_const) {
			var rang_list	= _cache['rang_list'];
			var user_rang	= rang_list[_cache['rang_id']];
			
			/** */
			if (user_rang.permission & action_const)
				return true;
			
			return false;
		}
		
		/** возвращаем ранг пользователя */
		t.getRangNameByUserId	= function(user_id) {
			var rang_list	= _cache['rang_list'];
			var users	= _cache['users'];
			
			if (typeof users[user_id] == 'undefined')
				return g('clan.leave_rang');
			
			var rang_id	= users[user_id].rang_id;
			
			return rang_list[rang_id].rang_name;
		}
		
		return t;
	}
	
	t.jsSettings		= jsSettingsHandler(t);
	function jsSettingsHandler(self) {
		var t	= {};
		t.self	= self;
		
		/** локальный кеш */
		var _cache	= {};
		
		t.insert	= function(conf) {
			for(var i in conf) {
				_cache[i]	= conf[i];
			}
		}
		
		t.set		= function(key,value) {
			_cache[key]	= value;
			var time	= new Date().getTime();
			API.call('profile.jsSettigns',{'key':key,'value':value,'type':'set','time':time},function(r){},function(r){});
		}
		
		t.setPack	= function(set,after) {
			after	= after || function(){};
			var time	= new Date().getTime();
			for (var i in set) {
				_cache[i]	= set[i];
			}
			API.call('profile.jsSettignsPack',{'pack':set,'time':time},after,after);
		}
		
		t.inc		= function(key,value) {
			API.call('profile.jsSettigns',{'key':key,'value':value,'type':'inc'},function(r){},function(r){});
		}
		
		t.dec		= function(key,value) {
			API.call('profile.jsSettigns',{'key':key,'value':value,'type':'dec'},function(r){},function(r){});
		}
		
		/** */
		t.getInfo	= function(key) {
			key	= key || 'all';
			
			if (key === 'all' || typeof key == 'undefined')
				return _cache;
			
			if (typeof _cache[key]!=='undefined')
				return _cache[key];
			
			//log(_cache);
			return key;
		}
		
		return t;
	}
	
	t.cache		= cacheHandler(t);
	function cacheHandler(self) {
		var t	= {};
		t.self	= self;
		
		/** локальный кеш */
		var _cache	= {};
		
		t.insert	= function(conf) {
			for(var i in conf) {
				_cache[i]	= conf[i];
			}
		}
		
		t.set		= function(key,value) {
			_cache[key]	= value;
		}
		
		/** */
		t.getInfo	= function(key,def) {
			key	= key || 'all';
			def	= def || key;
			
			if (key === 'all' || typeof key == 'undefined')
				return _cache;
			
			if (typeof _cache[key]!=='undefined')
				return _cache[key];
			
			return def;
		}
		
		/** */
		t.get		= function(key,def) {
			return t.getInfo(key,def);
		}
		
		return t;
	}
	
	t.social	= socialHandler(t);
	function socialHandler(self) {
		var t	= {};
		t.self	= self;
		
		/** локальный кеш  */
		var _cache	= {};
		
		t.set		= function(conf) {
			for(var i in conf) {
				_cache[i]	= conf[i];
			}
		}
		
		/** */
		t.getInfo	= function(key) {
			if (typeof key == 'undefined')
				return _cache;
			
			if (typeof _cache[key]!=='undefined')
				return _cache[key];
			
			return key;
		}
		
		return t;
	}
	
	t.swag	= swagHandler(t);
	function swagHandler(self) {
		var t	= {};
		t.self	= self;
		
		/** локальный кеш  */
		var _cache	= {};
		
		t.insert	= function(conf) {
			for(var i in conf) {
				_cache[i]	= conf[i];
			}
		}
		
		/** */
		t.getInfo	= function(key) {
			if (typeof key == 'undefined')
				return _cache;
			
			if (typeof _cache[key]!=='undefined')
				return _cache[key];
			
			return key;
		}
		
		/** */
		t.isActive	= function() {
			return t.getInfo('till') > time();
		}
		
		return t;
	}
	
	t.shown		= shownHandler(t);
	function shownHandler(self) {
		var t	= {};
		t.self	= self;
		
		/** локальный кеш  */
		var _cache	= {};
		
		t.add		= function(conf) {
			for(var i in conf) {
				_cache['shown_'+i]	= conf[i];
			}
		}
		
		/** */
		t.getInfo	= function(key,def) {
			def	= typeof def == 'undefined' ? 0 : def;
			key	= 'shown_' + key;
			if (typeof key == 'undefined')
				return _cache;
			
			if (typeof _cache[key]!=='undefined')
				return _cache[key];
			
			return def;
		}
		
		t.set		= function(key,value) {
			_cache['shown_'+key]	= value;
			API.call('shown.set',{'key':key,'value':value});
		}
		
		return t;
	}
	
	t.effects		= effectsHandler(t);
	function effectsHandler(self) {
		var t	= {};
		t.self	= self;
		
		/** локальный кеш  */
		var _cache	= {};
		
		t.insert	= function(conf) {
			for(var i in conf) {
				var effect = conf[i];
				if (typeof effect.effect_id != 'undefined' && effect.end_time > time())
					_cache[effect.effect_id]	= effect;
			}
		}
		
		/** */
		t.getInfo	= function(effect_id,key) {
			if (typeof key == 'undefined')
				return _cache;
			
			if (typeof _cache[effect_id]!=='undefined')
				return typeof key!= 'undefined' ?  _cache[effect_id][key] :  _cache[effect_id];
			
			return false;
		}
		
		/** */
		t.have		= function(effect_id) {
			if (typeof _cache[effect_id]!= 'undefined' && _cache[effect_id].end_time > time())
				return true;
			
			return false;
		}
		
		/** */
		t.get		= function(effect_id,key) {
			return t.getInfo(effect_id,key);
		}
		
		/** */
		t.set		= function(key,value) {
			
		}
		
		/** возвращает время окончания эффекта */
		t.getEnd	= function(effect_id) {
			return t.getInfo(effect_id,'end_time');
		}
		
		return t;
	}
	
	t.tab		= tabHandler(t);
	function tabHandler(self) {
		var t	= {};
		t.self	= self;
		
		/** */
		t.get	= function(tab_id,def) {
			return getSettings('tab_'+tab_id,def);
		}
		
		/** */
		t.set	= function(tab_id,key) {
			setSettings('tab_'+tab_id,key);
		}
		
		return t;
	}
	
	t.pet		= petHandler(t);
	function petHandler(self) {
		var t	= {};
		t.self	= self;
		
		/** локальный кеш  */
		var _cache	= {};
		
		t.insert	= function(conf) {
			for(var i in conf) {
				_cache[i]	= conf[i];
			}
			
			this.autoUpdate();
		}
		
		/** */
		t.getInfo	= function(key,def) {
			def	= def || null;
			
			if (typeof key == 'undefined')
				return _cache;
			
			if (typeof _cache[key]!=='undefined')
				return _cache[key];
			
			return def;
		}
		
		/** обновляем состояние зверушки */
		t.autoUpdate	= function() {
			
		}
		
		return t;
	}
	
	t.actions	= actionsHandler(t);
	function actionsHandler(self) {
		var t	= {};
		t.self	= self;
		
		/** локальный кеш  */
		var _cache	= {};
		
		t.insert	= function(conf) {
			for(var i in conf) {
				_cache[i]	= conf[i];
			}
		}
		
		/** */
		t.isActive	= function(key) {
			if (typeof _cache[key]!= 'undefined')
				return true;
		}
		
		/** */
		t.getTime	= function(key) {
			if (typeof _cache[key]!= 'undefined' && typeof _cache[key]['time']!= 'undefined')
				return _cache[key]['time']
			else 
				return false;
		}
		
		/** */
		t.getDate	= function(key) {
			if (typeof _cache[key]!= 'undefined' && typeof _cache[key]['date']!= 'undefined')
				return _cache[key]['date']
			else 
				return false;
		}
		
		/** */
		t.getInfo	= function(key,def) {
			def	= def || null;
			
			if (typeof key == 'undefined')
				return _cache;
			
			if (typeof _cache[key]!=='undefined')
				return _cache[key];
			
			return def;
		}
		
		return t;
	}
	
	return t;	
}

/** 
 *-------------------------------------------------------------------   
 *                       Enemy - чужой игрок 
 *-------------------------------------------------------------------   
 **/

function enemyHandler(user_id) {
	var t		= {};
	t.user_id	= user_id;
	
	/** главная страница игрока и все что с ней связанно */
	t.profile		= profileHandler(t);
	function profileHandler(self) {
		var t	= {};
		t.self	= self;
		
		/** локальный кеш  */
		var _cache	= {};
		
		t.set		= function(conf) {
			for(var i in conf) {
				_cache[i]	= conf[i];
				$('#'+i).html(digit(conf[i]));
			}
		}
		
		/** получаем информацию об игроке */
		t.getInfo	= function(key) {
			if (typeof _cache[key]!=='undefined')
				return _cache[key];
			
			return key;
		}
		
		/** alias */
		t.screenMain	= function() {
			this.showMain();
		}
		
		/** ссылка на мой профайл */
		t.getLink	= function() {
			return 'http://' + ENEMY.profile.getInfo('profile_url');
		}
		
		/** главный экран чужого персонажа */
		t.showMain	= function() {
			var vars	= {};
			var th		= this;
			var ok		= function(r) {
				_parseMain(r);
			}
			
			var error	= function(r) {
				bAlert(g('errors.enemy_'+r.code,{'id':this.self.user_id}));
				PLAYER.profile.screenMain();
			}
			
			API.call('enemy.getProfile',{'enemy_id':this.self.user_id},ok,error);
		}
		
		/**
		 *	--------------------------------------------------------
		 *				PROTECTED
		 *	--------------------------------------------------------
		 **/
		
		/** 
		 * обрабатываем ответ сервера, затем показываем страницу персонажа
		 * логика аналогична API.actions	
		 **/
		function _parseMain(r) {
			var ar_actions	= r.info;
			for(var i in ar_actions) {
				/** вов время вызова этого блока - все переменные пустые, т.к. ENEMY = enemyHandler(); т.е. объект Enemy создан с чистого листа */
				if (ar_actions[i].type == 'profile') {
					ENEMY.profile.set(ar_actions[i].data);
					USERJS.add(ar_actions[i].data);
				}
				
				if (ar_actions[i].type == 'about') {
					ENEMY.profile.set(ar_actions[i].data);
				}

				if (ar_actions[i].type == 'gifts') {
					ENEMY.gifts.set(ar_actions[i].data);
				}

				if (ar_actions[i].type == 'ordens') {
					ENEMY.ordens.set(ar_actions[i].data);
				}

				if (ar_actions[i].type == 'medals') {
					ENEMY.medals.set(ar_actions[i].data);
				}
			}
			_showProfile();
		}
		
		/** показываем страницу игрока. Вызывается после распарсивания ответа от сервера */
		function _showProfile() {
			var vars	= {
				'vars'	: {
					'stats'		: ENEMY.profile.getInfo('stats'),	// Характиристики
					'stat'		: ENEMY.profile.getInfo('stat'),	// статистика
					'about_html'	: ENEMY.profile.getInfo('about_html'),
					'ar_all_ordens'	: _getOrdensHtml(),
					'ar_all_medals'	: _getMedalsHtml()
				}
			};
			
			if (ENEMY.profile.getInfo('ban')!=0) {
				SKIN.main(SKIN.parse('enemy/enemy_ban',vars),SCREEN_ENEMY);
			} else {
				SKIN.main(SKIN.parse('enemy/enemy_main',vars),SCREEN_ENEMY);
			}
		}
		
		/** HTML массив с орденами */
		function _getOrdensHtml() {
			var ar_now	= ENEMY.ordens.getInfo();
			var ar_all_ordens	= [];
			var limit	= 24;

			for(var b in ar_now) {
				var txt	= '<div class="square active_square medal fl_l orden orden_{ID}" title="" onclick="GLOBAL.honor.showOrden(\'{ID}\')" onmouseover="TOOLTIP.show(this,{\'type\':\'ordens\',\'tooltip_id\':\'orden_{ID}\'});"></div>'.format({'ID':ar_now[b]});
				ar_all_ordens.push(txt);
			}

			/** дополняем пустыми полями */
			for (var a = count(ar_all_ordens); a<=limit;a++) {
				var txt	= '<div class="square active_square fl_l pointer"></div>';
				ar_all_ordens.push(txt);
			}
			
			return ar_all_ordens;
		}
		
		/** HTML массив с медалями */
		function _getMedalsHtml() {
			var ar_now		= ENEMY.medals.getInfo();
			var ar_all_medals	= [];
			var limit	= 24;
			for (var a=6;a>=1;a--) {
				for(var b in ar_now[a]) {
					var txt	= '<div class="square active_square medal fl_l level_{LEVEL}_1 medal_{ID}" title="" onclick="GLOBAL.honor.showMedal(\'{ID}\',\'{LEVEL}\')" onmouseover="TOOLTIP.show(this,{\'type\':\'medals\',\'tooltip_id\':\'medal_{LEVEL}_{ID}\'});"></div>'.format({'LEVEL':a,'ID':ar_now[a][b]});
					ar_all_medals.push(txt);
				}
			}

			/** дополняем пустыми полями */
			for (var a = count(ar_all_medals); a<=limit;a++) {
				var txt	= '<div class="square active_square fl_l pointer"></div>';
				ar_all_medals.push(txt);
			}
			
			return ar_all_medals;
		}
		
		return t;
	}
	
	t.gifts			= giftsHandler(t);
	function giftsHandler(self) {
		var t	= {};
		t.self	= self;
		
		/** локальный кеш  */
		var _cache	= {};
		
		t.set		= function(conf) {
			for(var i in conf) {
				_cache[i]	= conf[i];
			}
		}
		
		/** */
		t.getInfo	= function(key) {
			if (typeof _cache[key]!=='undefined')
				return _cache[key];
			
			return key;
		}
		
		/** перерисовываем счетчики игрока */
		t.show		= function() {
			for (var i in _cache) {
				$('#'+i).html(_cache[i]);
			}
		}
		
		return t;
	}
	
	t.medals		= medalsHandler(t);
	function medalsHandler(self) {
		var t	= {};
		t.self	= self;
		
		/** локальный кеш  */
		var _cache	= {};
		
		t.set		= function(conf) {
			for(var i in conf) {
				_cache[i]	= conf[i];
				$('#'+i).html(digit(conf[i]));
			}
		}
		
		/** */
		t.getInfo	= function(key) {
			if (typeof key == 'undefined')
				return _cache;
			
			if (typeof _cache[key]!=='undefined')
				return _cache[key];
			
			return key;
		}
		
		return t;
	}
	
	t.ordens		= ordensHandler(t);
	function ordensHandler(self) {
		var t	= {};
		t.self	= self;
		
		/** локальный кеш  */
		var _cache	= {};
		
		t.set		= function(conf) {
			for(var i in conf) {
				_cache[i]	= conf[i];
				$('#'+i).html(digit(conf[i]));
			}
		}
		
		/** */
		t.getInfo	= function(key) {
			if (typeof key == 'undefined')
				return _cache;
			
			if (typeof _cache[key]!=='undefined')
				return _cache[key];
			
			return key;
		}
		
		return t;
	}
	
	return t;
}

/** 
 *-------------------------------------------------------------------   
 *         USERJS - храним общую информацию о персонажах
 *-------------------------------------------------------------------   
 **/

function userJsHandler(user_id) {
	var t		= {};
	
	/**
	 * Объект с пользователями. Формат: {
	 * 'name'		: 'Имя персонажа',
	 * 'avatar'		: 'код аватара',
	 * 'city'		: 'навазние города',
	 * 'age'		: 'Возраст',
	 * 'user_id'		: :),
	 * 'level'		: 'уровень персонажа',
	 * 'life_energy_percent': 'Проценты здоровья',
	 * 'race'		: 'race',
	 * 'sex'		: 'sex',
	 * 'domain'		: 'домен',
	 * 'domain_url'		: 'абсолютная ссылка на персонажа',
	 * }
	 **/
	var _cache	= {
		'users'		: {},
		'social'	: {}
	}; 
	
	t.add		= function(user) {
		if (typeof user.user_id !== 'undefined') {
			_cache.users[user.user_id]	= user;
		}
	}
	
	t.addSocial	= function(user) {
		if (typeof user.user_id !== 'undefined') {
			_cache.social[user.user_id]	= user;
		}
	}
	
	/** возращает информацию о пользователи. Если нет инфы - возращает FALSE */
	t.get		= function(user_id) {
		if (typeof _cache.users[user_id] === 'undefined')
			return false;
		
		return _cache.users[user_id];
	}
	
	/** возвращает социальную информацию (имя, аватар) - если такая есть */
	t.getSocial	= function(user_id) {
		if (typeof _cache.social[user_id] === 'undefined')
			return false;
		
		return _cache.social[user_id];
	}
	
	/** показывает popup с предложением быстро написать сообещние персонажу */
	t.addMessage	= function(user_id,message) {
		this.message	= message || '';
		var th		= this;
		
		/** обработчик показа popup а также отправки самого сообщения */
		var handler	= function(user_id) {
			var t	= {};
			t.self	= th;
			t.data	= th.get(user_id);
			
			t.show	= function() {
				var txt		= this.html();
				var popup	= lPopup();
				
				
				popup.add({
					'title'		: 'Отправить сообщение',
					'width'		: 400,
					'message'	: txt,
					'simple'	: true
				});
				popup.show();
			}
			
			
			t.html	= function() {
				var data	= this.data;
				var avatar_url	= getAvatarUrl(data.avatar,'i');
				var age_info	= typeof this.data.city_age == 'undefined' || this.data.city_age =='' ?  'Возраст не указан' : this.data.city_age;
				
				var txt		= '\n\
					<div class="" style="padding: 8px 10px 4px 10px;">\n\
						<table cellspacing="0" cellpadding="0" border="0" class="" width="100%">\n\
							<tr>\n\
								<td class="image w60"  valign="top">\n\
									<div class="w50">\n\
										<a onclick="return ACTIONS.showProfile(\''+data.user_id+'\');" class="post_image" href="'+data.domain_url+'" target="_top">\n\
											<img src="'+avatar_url+'" height="50" style="border:1px solid #DDCDB8">\n\
										</a>\n\
									</div>\n\
								</td>\n\
								<td valign="top">\n\
									<div class="" >\n\
										<div class="clear_fix " >\n\
											<a onclick="return ACTIONS.showProfile(\''+data.user_id+'\');" href="'+data.domain_url+'" target="_top">\n\
												<span>'+data.name+'</span>\n\
											</a>\n\
										</div>\n\
										<div class="preview lh150 black" style="text-decoration: none!important;">\n\
											'+age_info+'\n\
										</div>\n\
									</div>\n\
								</td>\n\
							</tr>\n\
						</table>\n\
					</div>\n\
					<div class="" style="background: none repeat scroll 0 0 #F5EBD3;border-top: 1px solid #DDCDB8;padding: 12px 10px 10px;">\n\
						<div class="mb10">\n\
							<textarea type="text" style="width:370px;height:45px;color:black;" class="" id="userjs_text" name="userjs_text">'+this.self.message+'</textarea>\n\
						</div>\n\
						<table cellpadding="0" cellspacing="0" class="">\n\
							<tr>\n\
								<td class="left">\n\
									<div class="button inline left mr10" style="line-height:100%;">\n\
										<span onclick="USERJS.sendMessage(\''+data.user_id+'\'); GLOBAL.setObj(this);">Отправить</span>\n\
									</div>\n\
								</td>\n\
								<td>\n\
									<div class="left"><span class="blink" onclick="ACTIONS.mail.userCorrespondence.show(\''+data.user_id+'\');">Показать историю переписки</span></div>\n\
								</td>\n\
							</tr>\n\
						</table>\n\
					</div>\n';
				return txt;
			}
		
		
			t.show();	// запуск
		} // end handler
		
		handler(user_id);
	}
	
	/** отправить сообщение пользователю */
	t.sendMessage	= function(user_id) {
		var d		= this.get(user_id);
		var txt		= $('#userjs_text').val();
		
		if (txt == '')
			return false;
		
		var data	= {
			'message'	:txt,
			'to_user'	:d.user_id
		};
		
		/** отправляем сообщение на сервер */
		API.call('post.send',data,function(r){
			bAlert({
				'time'		: 3000,
				'title'		: g('location.post_send_balert_ok_title'),
				'text'		: g('location.post_send_ok')
			});
			lPopupRemove();
		},function(r){
			/** сообщение об ошибке */
			bAlert({
				'time'		: 3000,
				'title'		: g('error.post_balert_error_title'),
				'text'		: g('error.post_send_'+r.code)
			});
		});
	}
	
	return t;
}

/** 
 *-------------------------------------------------------------------   
 *                       Datastore - локальный кеш
 *-------------------------------------------------------------------   
 **/
function datastoreHandler() {
	var t	= {};
	
	return t;	
}

/** 
 *-------------------------------------------------------------------   
 * Отвечает за всплытие popup после покупки с предлоежнием разместить на стену, 
 * а также обрабатывает все социальные функции друзей, постинга на стену и т.п.
 *-------------------------------------------------------------------   
 **/
function vkSocialHandler() {
	var t	= {
		conf	: {
			app_settings	: [
				'1',	// Пользователь разрешил отправлять ему уведомления. 
				'2',	// Доступ к друзьям. 
				'4'	// Доступ к фотографиям. 
			//	'256',	// Добавление ссылки на приложение в меню слева. 
			//	'1024'	// Доступ к статусам пользователя. 
			]
		}
	};
	
	
	t.tell		= tellHandler(t);
	function tellHandler(self) {
		var t	= {};
		t.self	= self;
				
		/** рассказать у себя на стене о своей ссылкe */
		t.tellAboutMe	= function() {
			var data	= {
				'image_id'	: 'tell_about_me',
				'stat'		: 'about_me',
				'message'	: g('global.vk_tell_about_me') + PLAYER.profile.getLink()
			}
			
			if (PLAYER.cache.get(JS_CACHE_CAN_BLOT)==1) {
				data['need_blot']	= true;
				data['blot_type']	= 'standart';
			}
			
			SOCIAL.friends.postMyWall(data);
		}
		
		/** OLD рассказать у себя на стене о своеем бое */
		t.tellAboutFightLog	= function(log_id) {
			var data	= {
				'image_id'	: 'tell_about_fight_log',
				'stat'		: 'about_fight',
				'message'	: g('global.vk_tell_fight')  + APP_URL + '#fight' + log_id
			};
			
			if (PLAYER.cache.get(JS_CACHE_CAN_BLOT)==1) {
				data['need_blot']	= true;
				data['blot_type']	= 'standart';
			}
			
			SOCIAL.friends.postMyWall(data);
		}
		
		/** рассказать у себя на стене о своеем бое */
		t.tellFightLog		= function(info) {
			info['image_id']	= 'tell_fight_log';
			info['stat']		= 'about_fight';
			//info['message']		= g('global.vk_tell_fight')  + APP_URL + '#fight' + info.log_id,
			info['message']		= BOTVA_URL + 'fight' + info.log_id;
			
			if (PLAYER.cache.get(JS_CACHE_CAN_BLOT)==1) {
				info['need_blot']	= true;
				info['blot_type']	= 'standart';
			}
			
			SOCIAL.friends.postMyWall(info);
		}
		
		/** рассказать у себя на стене о levelup */
		t.tellAboutLevelUp	= function() {
			var data	= {
				'image_id'	: 'tell_about_levelup_' + PLAYER.profile.getInfo('level'),
				'stat'		: 'about_levelup',
				'message'	: PLAYER.profile.getInfo('level') + g('global.vk_tell_level_up') + "\n" + BOTVA_URL + 'up'+PLAYER.profile.getInfo('user_id') + '_' + PLAYER.profile.getInfo('level')
			};
			
			if (PLAYER.cache.get(JS_CACHE_CAN_BLOT)==1) {
				data['need_blot']	= true;
				data['blot_type']	= 'standart';
			}
			
			SOCIAL.friends.postMyWall(data);
		}
		
		/** рассказать на стене о новой вещи*/
		t.tellAboutItem		= function(item_id) {
			SOCIAL.friends.postMyWall({
				'image_id'	: 'tell_item_' + item_id,
				'stat'		: 'about_item',
				'after'		: function() {
					API.call('profile.getBribe',{'key':item_id},function(r){
						// ok
						bOk(g('global.bribe_ok'));
					},function(r) {
						bAlert(g('error.profile_'+r.code));
					});
					
					setSettings(JS_SETTINGS_TELL_ABOUT_ITEM,'1');
					ACTIONS.mail.main.show();
				},
				'message'	: g('global.vk_tell_item') + "\n" + PLAYER.profile.getLink()
			});
		}
		return t;
	}
	
	t.friends	= friendsHandler(t);
	function friendsHandler(self) {
		var t	= {
			'self'	: self
		}
			
		/** 
		 * главный обработчик друзей из ВК. Старый класс - начала берет в 2008-м 
		 * по мере доработки - будет рефакториться
		 **/
		t.handler	= fHandler(t);
		function fHandler(self)
		{
			var t = {
				'self'	: self
			};
			
			var _selected_count	= 0;
			var _timer_search	= 0;
			
			t.setup		= {multi:false,title:"",bottom_left:"",submenu:false,button_yes:false};
			t.friends_data	= []; // массив с друзьями пользователя - получам его с VK 
			t.exclude	= [];
			t.view_all_flag	= true;

			t.now_offset	= 0; // опции показа друзей
			t.show_limit	= 150;
			t.selected_data;
			t.search_data	= {};

			// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
			// Методы
			// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

			t.set	= function(param) // задаем настройки для окна друзей
			{
				if (param.multi) this.setup.multi = param.multi;
				if (param.title) this.setup.title = param.title;
				if (param.button_yes) this.setup.button_yes = param.button_yes;
			} // set

			/** единственная точка входа в класс */
			t.start	= function() {
				if (count(this.friends_data)==0) {
					this.getFriends();
				} else {
					this.show();
				}
			}

			/** получаем друзей */
			t.getFriends	 = function()
			{	
				var th	= this;
				if (SERVER_OS == 'vk') {
					var th	= this;
						VK.api(  
							'friends.get',  
							{  
							'uid': VK_ID,
							'fields' : 'uid, sex, first_name, last_name, photo, photo_medium, photo_big'
							},
							function(data) {
								th.vkResponse(data.response);
							}
						);
		//			}

				} else {
					this.vkResponse(this.self.getDemo());
				}
			} // get_friend_demo

			t.show = function() // показываем форму
			{
				var th = this;

				this.now_offset = 0;
				_selected_count = 0;
				this.selected_data = {};
				var txt = this.html_first();
				var show_more_txt = this.html_show_more();
				var sub_menu = this.html_submenu();

				var content	= "<div id='friend_top_sub_menu' class='pt6 pb6 pl8 pr10 w430'>" +sub_menu+ "</div>" 
					+ "<div style='overflow:auto;height:420px;padding:3px;'><div class='mt8 clear_fix' id='friend_content'>"+txt+"</div><div id='after_friend_content'>"+show_more_txt+"</div></div>"

				var pp	= oPopup();
		//		pp.set({width:481,height:255});
				pp.set({width:485});
				pp.set({title:this.setup.title});
				pp.set({'content': content});
				pp.show();
				this.bind();
				this.check_more();
			} // show

		
			t.view_all = function()
			{
				var limit = 0;
				limit = this.now_offset>0 ? this.now_offset : this.show_limit;
				this.now_offset = 0;
				jQuery('#friend_content').html('');
				var txt = this.html_first(0,limit); // показыаем dtm список друзей который раньше был
				jQuery('#friend_content').append(txt);
				this.bind();
				this.check_more();
			} // view_all

			t.view_search = function()
			{
				jQuery('#friend_content').html('');
				jQuery('.flist_more').css({"display":"none"});
				var txt = this.html_search();
				jQuery('#friend_content').append(txt);
				this.bind();
			} // view_search

			t.check_more = function()
			{
				var len = this.data_count();
				if (this.now_offset < len)
				{
					jQuery('#oPopup .class_more_questions').css({"display":"block"});
				}
				else
				{
					jQuery('#oPopup .class_more_questions').css({"display":"none"});
				}
			} // check_more

			t.show_more = function()
			{
				var txt = this.html_first();
				jQuery('#friend_content').append(txt);
				this.bind();
				this.check_more();
			} // show more

			t.data_count = function() // возращает кол-во друзей из массива
			{
				var ii=0;
				for (var v in this.friends_data) 
				{
					var tt = this.friends_data[v];
					if (tt)
					{
						ii++;
					}
				}
				return ii;
			} // data_count

			// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
			// служебные
			// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

			t.vkResponse = function(data) // разбирает ответ от VK 
			{
				if (data)
				{
					for(var vv in data)
					{
						var tt = data[vv];

						if (typeof this.exclude[tt.uid] != 'undefined')
							continue;

						this.friends_data[tt.uid] = tt;
					}
				}
				this.show();
			} //

			t.show_selected_debug = function()
			{		
				var text='';
				for(var v in this.selected_data)
				{
					var temp = this.selected_data[v];
					if (temp)
					{
						text += "selected_data["+v+"] = {'uid':'"+temp.uid+"', 'first_name':'"+temp.first_name+"', 'last_name':'"+temp.last_name+"', 'photo':'"+temp.photo+"', 'photo_medium':'"+temp.photo_medium+"', 'photo_big':'"+temp.photo_big+"'};  \n";			
					}
				}
				jQuery('#ajax_bottom').html('<textarea style="width:400px;height:100px;">'+text+'</textarea>');
			}

			t.search = function(search_key)
			{
				this.search_data = {}
				search_key = search_key.toLowerCase();
				var re = new RegExp('('+search_key+')', 'i');
				
				for (var v in this.friends_data) 
				{
					var tt = this.friends_data[v];
					if (tt)
					{
						var text = ' '+tt.last_name + ' ' +tt.first_name;
						text = text.toLowerCase();		
						var s =text.search(re)

						if (s>0) 
						{
							this.search_data[tt.uid] = tt;
						}
						
					}
				}
				this.view_search();
			}

			// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
			// обработчики
			// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

			t.buttonYesClick = function() //"выбрать"
			{
				this.setup.button_yes.action(this.selected_data);
				to_remove();
			} // button_yes_click

			t.bind = function() // устанавливаем обработчики на клик и т.п.
			{
				var th	= this;
				// удаляем обработчики, если есть
				$(".flist_cell").unbind();

				var prev_check;
				$(".flist_cell").bind("click", function(event){
					var uid = this.id.replace('flist_cell',"");

					if (!jQuery(this).hasClass('flist_cell_on'))
					{
						jQuery(this).removeClass('flist_cell_over');
						jQuery(this).addClass('flist_cell_on');


						if (th.setup.multi == true)
						{
							//if (cl_friend.selected_data==false) { cl_friend.selected_data = [];}
							th.selected_data[uid] = th.friends_data[uid];
							_selected_count += 1;
						}
						else // если не стоит мульти выбор
						{
							th.selected_data = {};
							th.selected_data = th.friends_data[uid];
							if (prev_check) {th.selected_data[prev_check.replace('flist_cell',"")] = false;}
							jQuery('#'+prev_check).removeClass('flist_cell_on');
							_selected_count = 1;

							/** эмулируем как-буд-то мы дальше нажали применить */
							th.buttonYesClick();
							return false;
						}

						prev_check = this.id;
					}
					else
					{
						jQuery(this).removeClass('flist_cell_on');
						if (th.setup.multi  == true)
						{
							th.selected_data[uid] = false;
							_selected_count += 1;

						}
						else // если не стоит мульти выбор
						{
							th.selected_data = {};
							th.selected_data[uid] = false;
							_selected_count = 0;
						}
					}

					jQuery('#selected_count').html(_selected_count);
				}); // конец клика


				$(".flist_cell").bind("mouseover", function(event){
						if (!jQuery(this).hasClass('flist_cell_on'))
						jQuery(this).addClass('flist_cell_over');
				});


				$(".flist_cell").bind("mouseout", function(event){
						if (!jQuery(this).hasClass('flist_cell_on'))
						jQuery(this).removeClass('flist_cell_over');
				});	


				$(".flist_cell").bind("mouseout", function(event){
						if (!jQuery(this).hasClass('flist_cell_on'))
						jQuery(this).removeClass('flist_cell_over');
				});	

				$("#search_friend").unbind().live('keyup', function() 
				{
					if($(this).val() == '') { 
						if (th.view_all_flag == true) {
							th.view_all_flag	= false;
							th.view_all();
						}
						return false;
					}
					var search_key = $(this).val() ;
					if  (search_key == 'g123') {th.check_all();return false;}
					if  (search_key == 'g456') {th.check_456();return false;}
					if  (search_key == 'g10') {th.check_10();return false;}
					clearTimeout(_timer_search);
					_timer_search = setTimeout(function(p){ 
						th.search(search_key);
						th.view_all_flag	= true;
					},300);
				}); // конец поиска


				$("#search_friend").unbind().bind('click', function() // скрываем подсказку при клике по поиску
				{
					if (jQuery('#friend_search_hint').css('display')=='block')
					{
						jQuery('#friend_search_hint').css({"display":"none"});
					}
				}); 


			}

			// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
			// Html представление
			// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

			t.html_first = function(offset,limit) // показываем весь список
			{
				limit = limit || this.show_limit;
				offset = offset || this.now_offset;
				var ii=0;
				var txt='';
				var cls = '';
				for (var v in this.friends_data) 
				{
					var tt = this.friends_data[v];
					if (tt)
					{
						ii++;
						if (ii<=offset) continue;

						if (this.selected_data[tt.uid]) {cls = 'flist_cell flist_cell_on';} else {cls = 'flist_cell';}
						txt += this.html_f(tt,cls);

						if (ii-offset >= limit) break;
					}

				}
				this.now_offset = ii;
				return txt;
			} //

			t.html_selected = function() // показываем только выделенные элементы
			{
				var txt='';
				var cls = '';
				for (var v in this.friends_data) 
				{
					var tt = this.friends_data[v];
					if (tt)
					{
						if (this.selected_data[tt.uid]) {cls = 'flist_cell flist_cell_on';txt += this.html_f(tt,cls);} 
					}

				}
				return txt;
			} //

			t.html_search = function() // показываем только выделенные элементы
			{
				var txt='';
				var cls = '';
				for (var v in this.search_data) 
				{
					var tt = this.search_data[v];
					if (this.selected_data[tt.uid]) {cls = 'flist_cell flist_cell_on';} else {cls = 'flist_cell';}
					txt += this.html_f(tt,cls);
				}
				return txt;
			} //

			t.html_f = function(tt,cls)
			{
				var txt ='<div id="flist_cell'+tt.uid+'" class="'+cls+'">'+
						'	<div class="flist_border_wrap">'+
						'	  <div class="flist_wrap">'+
						'		<div class="flist_div">'+
						'		  <div class="flist_image">'+
						'			<img src="'+tt.photo+'">'+
						'		  </div>'+
						'		</div>'+
						'		<div class="flist_name">'+tt.first_name+' ' +tt.last_name+'</div>'+
						'	  </div>'+
						'	</div>'+
						'  </div>';
				return txt;
			}

			t.html_show_more = function()
			{
				var text = '<div class="read_more clear_fix pt10 pb10" onmouseover="SOCIAL.friends.handler.show_more();"><div></div></div>';
				return text;
			}

			t.html_submenu = function()
			{
				var text = 
				'<div class="tabs clear_fix" style="width:436px;">'+
				'	<div class="fl_l">'+
				'		<div class="input_back" style="margin-top: 0px; margin-left: 0px; margin-right: 0px; padding-top: 3px; padding-left: 3px; padding-right: 3px; width: 400px; height: 17px;">'+
				'			<div style="" id="friend_search_hint">'+
				'				Начните вводить имя друга'+
				'			</div>'+
				'		</div>'+
				'		<input type="text" class="text" id="search_friend" style="width: 424px; background-color: transparent; z-index: 91; position: relative;" placeholder="">'+
				'	</div>'+
				'</div>';

				return text;
			} // html_submenu;

			return t;
		} // 
			
		/** отдаем демо список друзей */
		t.getDemo	= function() {
			var demo = {};
			demo.response = [];
			demo.response[0] = {'uid':'187541','sex':1, 'first_name':'Бык', 'last_name':'Фанерный', 'photo':'http://cs10273.vkontakte.ru/u187541/e_9dba4203.jpg', 'photo_medium':'http://cs10273.vkontakte.ru/u187541/b_616edc92.jpg', 'photo_big':'http://cs10273.vkontakte.ru/u187541/a_26440879.jpg'};  
			demo.response[1] = {'uid':'696150','sex':1, 'first_name':'Евгений', 'last_name':'Яковлев', 'photo':'http://cs10349.vkontakte.ru/u696150/e_5249d11c.jpg', 'photo_medium':'http://cs10349.vkontakte.ru/u696150/b_456d8844.jpg', 'photo_big':'http://cs10349.vkontakte.ru/u696150/a_95d7a794.jpg'};  
			demo.response[2] = {'uid':'821732','sex':1, 'first_name':'Юрий', 'last_name':'Мясников', 'photo':'http://cs4851.vkontakte.ru/u821732/e_58886a8b.jpg', 'photo_medium':'http://cs4851.vkontakte.ru/u821732/b_b9bc6c20.jpg', 'photo_big':'http://cs4851.vkontakte.ru/u821732/a_5130cef1.jpg'};  
			demo.response[3] = {'uid':'1121773','sex':1, 'first_name':'Александр', 'last_name':'Осипов', 'photo':'http://cs9858.vkontakte.ru/u1121773/e_311b079c.jpg', 'photo_medium':'http://cs9858.vkontakte.ru/u1121773/b_57ea1b35.jpg', 'photo_big':'http://cs9858.vkontakte.ru/u1121773/a_e4edb6b2.jpg'};  
			demo.response[4] = {'uid':'187541','sex':1, 'first_name':'Бык', 'last_name':'Фанерный', 'photo':'http://cs10273.vkontakte.ru/u187541/e_9dba4203.jpg', 'photo_medium':'http://cs10273.vkontakte.ru/u187541/b_616edc92.jpg', 'photo_big':'http://cs10273.vkontakte.ru/u187541/a_26440879.jpg'};  
			demo.response[5] = {'uid':'696150','sex':1, 'first_name':'Евгений', 'last_name':'Яковлев', 'photo':'http://cs10349.vkontakte.ru/u696150/e_5249d11c.jpg', 'photo_medium':'http://cs10349.vkontakte.ru/u696150/b_456d8844.jpg', 'photo_big':'http://cs10349.vkontakte.ru/u696150/a_95d7a794.jpg'};  
			demo.response[6] = {'uid':'821732','sex':1, 'first_name':'Юрий', 'last_name':'Мясников', 'photo':'http://cs4851.vkontakte.ru/u821732/e_58886a8b.jpg', 'photo_medium':'http://cs4851.vkontakte.ru/u821732/b_b9bc6c20.jpg', 'photo_big':'http://cs4851.vkontakte.ru/u821732/a_5130cef1.jpg'};  
			demo.response[7] = {'uid':'1121773','sex':1, 'first_name':'Александр', 'last_name':'Осипов', 'photo':'http://cs9858.vkontakte.ru/u1121773/e_311b079c.jpg', 'photo_medium':'http://cs9858.vkontakte.ru/u1121773/b_57ea1b35.jpg', 'photo_big':'http://cs9858.vkontakte.ru/u1121773/a_e4edb6b2.jpg'};  
			demo.response[8] = {'uid':'187541','sex':1, 'first_name':'Бык', 'last_name':'Фанерный', 'photo':'http://cs10273.vkontakte.ru/u187541/e_9dba4203.jpg', 'photo_medium':'http://cs10273.vkontakte.ru/u187541/b_616edc92.jpg', 'photo_big':'http://cs10273.vkontakte.ru/u187541/a_26440879.jpg'};  
			demo.response[9] = {'uid':'696150','sex':1, 'first_name':'Евгений', 'last_name':'Яковлев', 'photo':'http://cs10349.vkontakte.ru/u696150/e_5249d11c.jpg', 'photo_medium':'http://cs10349.vkontakte.ru/u696150/b_456d8844.jpg', 'photo_big':'http://cs10349.vkontakte.ru/u696150/a_95d7a794.jpg'};  
			demo.response[10] = {'uid':'821732','sex':1, 'first_name':'Юрий', 'last_name':'Мясников', 'photo':'http://cs4851.vkontakte.ru/u821732/e_58886a8b.jpg', 'photo_medium':'http://cs4851.vkontakte.ru/u821732/b_b9bc6c20.jpg', 'photo_big':'http://cs4851.vkontakte.ru/u821732/a_5130cef1.jpg'};  
			demo.response[11] = {'uid':'1121773','sex':1, 'first_name':'Александр', 'last_name':'Осипов', 'photo':'http://cs9858.vkontakte.ru/u1121773/e_311b079c.jpg', 'photo_medium':'http://cs9858.vkontakte.ru/u1121773/b_57ea1b35.jpg', 'photo_big':'http://cs9858.vkontakte.ru/u1121773/a_e4edb6b2.jpg'};  
			demo.response[12] = {'uid':'187541','sex':1, 'first_name':'Бык', 'last_name':'Фанерный', 'photo':'http://cs10273.vkontakte.ru/u187541/e_9dba4203.jpg', 'photo_medium':'http://cs10273.vkontakte.ru/u187541/b_616edc92.jpg', 'photo_big':'http://cs10273.vkontakte.ru/u187541/a_26440879.jpg'};  
			
			for (var a=1;a<=400;a++) {
				var temp	= clone(demo.response[mt_rand(0,12)]);
				temp.uid	= a;
				demo.response.push(temp);
			}
			
			return demo.response;
		}
		
		/** вызываем окно приглашения для друзей */
		t.inviteBox	= function() {
			VK.callMethod('showInviteBox');
		}
		
		/** показываем окно выбора друзей. После выбора друга возвращает его id - в функция after */
		t.showBox	= function(config) {
			this.handler.set({
				title		:typeof config.title != 'undefined' ? config.title : 'Выберите друга',
				multi		:false,
				button_yes	:{title:'Выбрать',action:function(data) {if (typeof config.after!= 'undefined' ) {config.after(data);}to_remove();}}
			});
			
			if (typeof config.exclude!='undefined')
				this.handler.exclude	= config.exclude;
			else 
				this.handler.exclude	= [];
			
			/** show  */
			this.handler.start();
		}
		
		/** получаем список друзей кто уже установил это приложение из твоих друзей */
		t.getInApp	= function(after) {
			if (SERVER_OS == 'local') {
				var bb	= ["10000","169953","279695","452518","548301","1410633","1540319","1777629","1895834","2285650","2906680","3691975","3768870","3830880","3849180","4286609","4397275","6143609","6259107","6434783","6609719","6674166","7506208","7507211","7987311","8696054","9094628","9434945","9438952","9544564","9745570","10005495","10431029","10439407","10616422","11039478","11073019","11484261","11874830","12125935","12445702","13633966","13969948","14443845","15107590","15592730","16657355","16903325","18086743","18212878","19459423","20746706","20870728","20880102","22880705","23106410","23196318","23290340","23602539","23953430"];
				var output	= [];
				for (var i in bb) {
					if (bb[i]!=VK_ID)
						output.push(bb[i]);
				}

				return after(output);
			}
			
			if (SERVER_OS == 'vk') {
				/** вызываем из VK */
				VK.api(  
					'friends.getAppUsers',{},
					function(data) {
						after(data.response);
					}
				);
			}
		}
		
		/** пригласить друга */
		t.inviteListAndPostWall	= function() {
			this.postFriendWall({
				'image_id'	: 'invite_friends_rand',
				'stat'		: 'invite_friend',
				'message'	: g('global.vk_invite_friend_main')
			});
		}
		
		
		
		/** публикуем у друга на стене */
		t.postFriendWall	= function(info) {
			SOCIAL.friends.showBox({
				'after'		: function(data) {
					//log(data);
					info.stat	= info.stat || 'friend_other';
					info.after	= info.after || function(){};
					info.reciver_id	= data.uid;
					_postImageOnWall(info);
				}
			});
		}
		
		/** публикуем у себя на стене */
		t.postMyWall		= function(info) {
			info.stat	= info.stat || 'other';
			info.after	= info.after || function(){};
			info.reciver_id	= VK_ID;
			_postImageOnWall(info);
		}
		
		/** публикуем у себя на стене */
		t.postWall		= function(info) {
			info.stat	= info.stat || 'other';
			info.after	= info.after || function(){};
			_postImageOnWall(info);
		}
		
		/**
		 *	----------------------------------------------------
		 *			PROTECTED 
		 *	----------------------------------------------------
		 **/
		
		/** разместить информацию на стене */
		function _postImageOnWall(dd) {
			/** подготавливаем данные для отправки */
			
//			image_id,reciver_id,message,stat,after
//			var dd	= {};
//			dd.message	= message;
//			dd.reciver_id	= reciver_id;
//			dd.image_id	= image_id;
//			dd.stat		= stat;

			/** 
			* процесс такой: 
			* 1. Получаем у ВК адресс для загрузки фоток
			* 2. Отсылаем адресс и и общую информацию об оценках на наш сервер
			* 3. Загружаем сгенерированную картинку в ВК
			* 4. Возращаем данные для attachent в формате json
			**/
			var handler	= function(dd) {
				var t			= this;
				t.dd			= dd;
				t.attachment		= [];
				t.responseServerData	= {}; // наш ответ от сервера

				/** получаем данные для загрузки данных на сервер из контакта */
				t.getUrlFromVk		= function() {
					var th	= this;

					if (SERVER_OS == 'local') {
						this.sendDataToServer('http://url_to_upload.demo');
						return false;
					}

					VK.api(  
						'photos.getWallUploadServer',  
						{ 
							'uid': th.dd.reciver_id
						},  
						function(dd) {
							if (typeof dd.response != 'undefined') {
								if (typeof dd.response.upload_url != 'undefined')
								{
									th.sendDataToServer(dd.response.upload_url);
								} else {
									somethingError('VK error: photos.getWallUploadServer()');
								}
							} else {
								somethingError('VK error: photos.getWallUploadServer()');
							}
						}
					);
				}

				/** грузим к нам на серверер */
				t.sendDataToServer	= function(url) {
					var th		= this;
					th.dd.url	= url;
					API.call('social.vkUpload',th.dd,th.responseServer,somethingError);
				}

				/** jndtn jn yfituj cthdthf */
				t.responseServer	= function(rsData) {
					rsData				= rsData || this.responseServerData;
					this.responseServerData		= rsData;
					/** 
					* 'status'	= 'ok' | 'need_upload'
					* 'dd'	= ''	данные для отправки уже на стену \ либо для загрузки фотки и получения о ней данных
					**/

					if (SERVER_OS == 'local') {
						this.report();
						return false;
					}

					var th	= this;
					var i	= 0;
					for(var a in rsData.data) {
						var info	= rsData.data[a];
						if (typeof info.status != 'undefined') {
							i++;
							if (typeof th.attachment[i] != 'undefined')
								continue;

							if (info.status=='need_upload') {
								//log('need_upload');
								th.needUpload(info.data,i);
								return false;
							}
							else {
								//log('attachment');
								th.attachment[i]	= info.data;
							}
						}
					}

					th.publicOnWallVk();
					return false;
				}

				/** надо hash полученный от нашего сервера сконвертировать в фото объект */
				t.needUpload		= function(dd,i) {
					var th		= this;
					var a		= function() {
						VK.api(  
							'photos.saveWallPhoto',  
							{  
								'server'	: dd.server,
								'photo'		: dd.photo,
								'hash'		: dd.hash
							},  
							function(dd) {
								if (typeof dd.response != 'undefined') {
									if (typeof dd.response[0].id != 'undefined')
									{
										//log(dd.response[0].id);
										th.attachment[i]	= dd.response[0].id;
										//post('gifts','updategiftsvkdd',{ 'id':dd.response[0].id,'gift_id':gift_id});
										th.responseServer();
										return true;
									} else {
										th.attachment[i]	= '';
										th.responseServer();
										return false;
										//somethingError();
									}
								} else {
									//somethingError();
									th.attachment[i]	= '';
									th.responseServer();
									return false;
								}

								th.responseServer();
							}
						);
					}

					a();
					return false;
				}

				/** когда все готово - публикуем на стену */
				t.publicOnWallVk	= function() {
					var th	= this;
					VK.api(  
						'wall.post',  
						{  
							'owner_id'	: th.dd.reciver_id,
							'message'	: th.dd.message,
							'attachments'	: implode(",",th.attachment)
						},  
						function(dd) {
							if (typeof dd.response != 'undefined') {
								if (typeof dd.response.post_id != 'undefined')
								{
									th.report(dd.response.post_id);
								}
							}
						}
					);
				}

				/** */
				t.start			= function() {
					var th		= this;
					th.getUrlFromVk();
				}

				/** уведомленмя сервер об успешном приглашении, а пользователя что его другу ушла заявка  */
				t.report		= function(post_id) {
					var th	= this;
					if (th.dd.reciver_id == VK_ID)
						bOk(g('global.vk_social_post_me'));
					else
						bOk(g('global.vk_social_invite_ok'));
					
					if (typeof th.dd.stat != 'undefined' && th.dd.stat!='' && th.dd.stat!=false) {
						// отправляем статистику на сервер 
						API.call('service.statTell',{'key':th.dd.stat});
					}
					
					/** откаты, кляксыб и фиксация */
					if (typeof th.dd.need_blot != 'undefined' && th.dd.need_blot == true) {
						API.call('blot.statBlot',{'post_id':post_id,'blot_type':th.dd.blot_type},function(){
							bRemove();
							lAlert(g('location.blot_stat_save_ok'));
						});
					}
					
					/** после - выполняем действия */
					if (typeof after != 'undefined') {
						after();
					}
				}

				/** end */
				return t;
			}

			/** запускаем локальный обработчик */
			var h	= handler(dd);
			h.start();
		}
		
		
		return t;
	}
	
	/** базовая информация из соц сети */
	t.info		= infoHandler(t);
	function infoHandler(self) {
		var t	= {
			'self'	: self
		};
		
		/** возвращает имя, фамилию и т.п */
		t.getMain	= function(after) {
			var output	= {
				'name'	: '[soc] ' + PLAYER.profile.getInfo('name'),
				'photo'	: ADATA_URL + '/avatars/i' + zorro(PLAYER.profile.getInfo('avatar')) + '.jpg',
				'sex'	: 0
			};
			
			if (SERVER_OS == 'local') {
				return after(output);
			}
			
			if (SERVER_OS == 'vk') {
				/** -- -- */
				VK.api(  
					'users.get',  
					{  
						'uids': VK_ID,
						'fields' : 'sex, first_name, last_name, photo'
					},
					function(data) {
						var res		= data.response;
						output.photo	= res[0].photo;
						output.name	= res[0].first_name + ' ' + res[0].last_name;
						output.sex	= res[0].sex;

						after(output);
					}
				);
			}
		}
		
		/** устанавливаем звначение в левом меню */
		t.setCounter	= function(value) {
			if (SERVER_OS != 'vk') {
				return ;
			}
			
			VK.api('setCounter',  
				{  
					'counter': value
				}
			);
				
			VK.api('setNameInMenu',  
				{  
					'name': 'Ботва Онлайн'
				}
			);	
		}
		
		/** проверяем ссылку на приложение в меню слева */
		t.checkLeft	= function(after) {
			this.wellcome.add({'need_settings' : [256]}).start(after);
		}
		
		/** проверяем настройки приложения */
		t.wellcome	= wellcomeHandler(t);
		function wellcomeHandler(self) {
			var t	= {
				self		: self,
				need_settings	: self.self.conf.app_settings,
				after		: function() {}
			};			

			t.add	= function(config) {
				if (typeof config.need_settings!= 'undefined') {
					t.need_settings	= config.need_settings;
				}
				
				return this;
			}

			/** кликнули по кнопке, проверяем настройки  */
			t.start	= function(after) {
				var th		= this;
				
				if (typeof after !='undefined')
					this.after	= after;
				
				if (SERVER_OS == 'local')
					return this.after();

				_addApp();
			}

			
			/**
			 * -----------------------------------------------------
			 *			PROTECTED
			 * -----------------------------------------------------
			 **/
			
			/** добавляем приложение */
			function _addApp() {
				var th	= t;
				VK.callMethod('showInstallBox');
				VK.addCallback('onApplicationAdded', function(){			
					/** если приложение установлено уже - проверяем настройки */
					VK.api('getUserSettings',{}, function(app_set) {
						if (_checkApiSettings(app_set.response))
						{
							return t.after();
						} else {
							_changeSettings();
						}
					});
					
				});
			}
			
			/** изменяем настройки для приложения  */
			function _changeSettings() {
				var th	= t;
				VK.callMethod('showSettingsBox',_getSettingsBit());
				VK.addCallback('onSettingsChanged', function(app_set){
					//log(app_set);
					if (_checkApiSettings(app_set))
					{
						return t.after();
					} else {
						//log('api_settings_error_msg');
						//bAlert(g('error.vk_app_settings_error_msg'));
						lAlert({
							'message'	: g('error.vk_app_settings_error_msg'),
							'action'	: function() {
								setTimeout(function(){
									SOCIAL.info.wellcome.start(SOCIAL.info.wellcome.after);
								},3000);
							}
						});
					}
				});
			}
			
			/** возращает необходимую битовую маску для приложения */
			function _getSettingsBit() {
				var bit	= 0;
				for(var a in t.need_settings) {
					bit += parseInt(t.need_settings[a]);
				}
				return bit;
			}
			
			/** проверяем настройки которые нам вернули */
			function _checkApiSettings(app_set) {
				for(var a in t.need_settings) {
					if (!(parseInt(app_set) & parseInt(t.need_settings[a])) ) {
						//log('vK_set_app ' + app_set + ' - bit ' + t.need_settings[a]);
						//log(app_set);
						return false;
					}
				}
				return true;
			}
			
			return t; // wellcome_handler
		}
		
		t.checkPost	= function(post_id,after) {
			if (SERVER_OS == 'local') {
				return after(1);
			}
			
			/** -- -- */
			VK.api(  
				'wall.getById',  
				{  
					'posts': VK_ID + '_' + post_id
				},
				function(data) {
					var response	= data.response;
					var res = 0;
					if (typeof response[0]!='undefined' && typeof response[0]['id']!='undefined' && response[0]['id'] == post_id) 
						res = 1;
					
					after(res);
				}
			);
		}
		
		return t;
	}
	
	t.service	= serviceHandler(t)
	function serviceHandler(self) {
		var t	= {
			self	: self
		}
		
		/** обновляем онлайн друзей кто есть в приложении */
		t.updateFriendOnline	= function() {
			if (SERVER_OS != 'vk')
				return false;
			
			/** если недавно проверяли */
			var tt = getSettings(JS_SETTINGS_UPDATE_ONLINE_FRIENDS,0);
			if (!DEV_SERVER && parseInt(tt) > parseInt(time()-600))
				return false;
			
			setSettings(JS_SETTINGS_UPDATE_ONLINE_FRIENDS,time());
			/** получаем список друзей кто он лайн */
			VK.api('friends.getOnline',{}, function(r) {
					var list	= typeof r.response != 'undefined' ? r.response : [];
					var all		= {};
					var i		= 0;
					for (i in list) {
						var vk_id	= list[i];
						all['i'+vk_id]	= vk_id;
					}
					
					if (i == 0)
						return;
					
					/** кто в приложении */
					VK.api('friends.getAppUsers',{}, function(r) {
						var list	= typeof r.response != 'undefined' ? r.response : [];
						var need	= [];
						for (var i in list) {
							var key = list[i];
							if (typeof all['i'+key]!= 'undefined') {
								need.push(key);
							}
						}
						
						
						if (count(need)<1)
							return false;

						var need_txt	= need.join(',');
						/**  получаем инфрмацию о друзьях */
						VK.api('users.get',{uids:need_txt,fields:'uid,first_name,last_name,sex'}, function(r) {
							var list	= typeof r.response != 'undefined' ? r.response : [];
							API.call('service.updateFriendOnline',{'data':list});
						});
					});
				}
			);
		
		}
		
		return t;
	}
	return t;
}


/** 
 *-------------------------------------------------------------------   
 * Отвечает за всплытие popup после покупки с предлоежнием разместить на стену, 
 * а также обрабатывает все социальные функции друзей, постинга на стену и т.п.
 *-------------------------------------------------------------------   
 **/
function okSocialHandler() {
	var t	= {
		conf	: {
			app_settings	: [
				'1',	// Пользователь разрешил отправлять ему уведомления. 
				'2',	// Доступ к друзьям. 
				'4'	// Доступ к фотографиям. 
			//	'256',	// Добавление ссылки на приложение в меню слева. 
			//	'1024'	// Доступ к статусам пользователя. 
			]
		}
	};
	
	
	t.tell		= tellHandler(t);
	function tellHandler(self) {
		var t	= {};
		t.self	= self;
				
		/** рассказать у себя на стене о своей ссылкe */
		t.tellAboutMe		= function() {
			var data	= {
				'image_id'	: 'tell_about_me',
				'stat'		: 'about_me',
				'message'	: g('global.vk_tell_about_me') + PLAYER.profile.getLink()
			}
			
			if (PLAYER.cache.get(JS_CACHE_CAN_BLOT)==1) {
				data['need_blot']	= true;
				data['blot_type']	= 'standart';
			}
			
			SOCIAL.friends.postMyWall(data);
		}
		
		/** OLD рассказать у себя на стене о своеем бое */
		t.tellAboutFightLog	= function(log_id) {
			var data	= {
				'image_id'	: 'tell_about_fight_log',
				'stat'		: 'about_fight',
				'message'	: g('global.vk_tell_fight')  + APP_URL + '#fight' + log_id
			};
			
			if (PLAYER.cache.get(JS_CACHE_CAN_BLOT)==1) {
				data['need_blot']	= true;
				data['blot_type']	= 'standart';
			}
			
			SOCIAL.friends.postMyWall(data);
		}
		
		/** рассказать у себя на стене о своеем бое */
		t.tellFightLog		= function(info) {
			info['image_id']	= 'tell_fight_log';
			info['stat']		= 'about_fight';
			//info['message']		= g('global.vk_tell_fight')  + APP_URL + '#fight' + info.log_id,
			info['message']		= BOTVA_URL + 'fight' + info.log_id;
			
			if (PLAYER.cache.get(JS_CACHE_CAN_BLOT)==1) {
				info['need_blot']	= true;
				info['blot_type']	= 'standart';
			}
			
			SOCIAL.friends.postMyWall(info);
		}
		
		/** рассказать у себя на стене о levelup */
		t.tellAboutLevelUp	= function() {
			var data	= {
				'image_id'	: 'tell_about_levelup_' + PLAYER.profile.getInfo('level'),
				'stat'		: 'about_levelup',
				'message'	: PLAYER.profile.getInfo('level') + g('global.vk_tell_level_up') + "\n" + BOTVA_URL + 'up'+PLAYER.profile.getInfo('user_id') + '_' + PLAYER.profile.getInfo('level')
			};
			
			if (PLAYER.cache.get(JS_CACHE_CAN_BLOT)==1) {
				data['need_blot']	= true;
				data['blot_type']	= 'standart';
			}
			
			SOCIAL.friends.postMyWall(data);
		}
		
		/** рассказать на стене о новой вещи*/
		t.tellAboutItem		= function(item_id) {
			SOCIAL.friends.postMyWall({
				'image_id'	: 'tell_item_' + item_id,
				'stat'		: 'about_item',
				'after'		: function() {
					API.call('profile.getBribe',{'key':item_id},function(r){
						// ok
						bOk(g('global.bribe_ok'));
					},function(r) {
						bAlert(g('error.profile_'+r.code));
					});
					
					setSettings(JS_SETTINGS_TELL_ABOUT_ITEM,'1');
					ACTIONS.mail.main.show();
				},
				'message'	: g('global.vk_tell_item') + "\n" + PLAYER.profile.getLink()
			});
		}
		return t;
	}
	
	t.friends	= friendsHandler(t);
	function friendsHandler(self) {
		var t	= {
			'self'	: self
		}
			
		/** 
		 * главный обработчик друзей из ВК. Старый класс - начала берет в 2008-м 
		 * по мере доработки - будет рефакториться
		 **/
		t.handler	= fHandler(t);
		function fHandler(self)
		{
			var t = {
				'self'	: self
			};
			
			var _selected_count	= 0;
			var _timer_search	= 0;
			
			t.setup		= {multi:false,title:"",bottom_left:"",submenu:false,button_yes:false};
			t.friends_data	= []; // массив с друзьями пользователя - получам его с VK 
			t.exclude	= [];
			t.view_all_flag	= true;

			t.now_offset	= 0; // опции показа друзей
			t.show_limit	= 150;
			t.selected_data;
			t.search_data	= {};

			// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
			// Методы
			// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

			t.set	= function(param) // задаем настройки для окна друзей
			{
				if (param.multi) this.setup.multi = param.multi;
				if (param.title) this.setup.title = param.title;
				if (param.button_yes) this.setup.button_yes = param.button_yes;
			} // set

			/** единственная точка входа в класс */
			t.start	= function() {
				if (count(this.friends_data)==0) {
					this.getFriends();
				} else {
					this.show();
				}
			}

			/** получаем друзей */
			t.getFriends	 = function()
			{	
				var th	= this;
				if (SERVER_OS == 'vk') {
					var th	= this;
						VK.api(  
							'friends.get',  
							{  
							'uid': VK_ID,
							'fields' : 'uid, sex, first_name, last_name, photo, photo_medium, photo_big'
							},
							function(data) {
								th.vkResponse(data.response);
							}
						);
		//			}

				} else {
					this.vkResponse(this.self.getDemo());
				}
			} // get_friend_demo

			t.show = function() // показываем форму
			{
				var th = this;

				this.now_offset = 0;
				_selected_count = 0;
				this.selected_data = {};
				var txt = this.html_first();
				var show_more_txt = this.html_show_more();
				var sub_menu = this.html_submenu();

				var content	= "<div id='friend_top_sub_menu' class='pt6 pb6 pl8 pr10 w430'>" +sub_menu+ "</div>" 
					+ "<div style='overflow:auto;height:420px;padding:3px;'><div class='mt8 clear_fix' id='friend_content'>"+txt+"</div><div id='after_friend_content'>"+show_more_txt+"</div></div>"

				var pp	= oPopup();
		//		pp.set({width:481,height:255});
				pp.set({width:485});
				pp.set({title:this.setup.title});
				pp.set({'content': content});
				pp.show();
				this.bind();
				this.check_more();
			} // show

		
			t.view_all = function()
			{
				var limit = 0;
				limit = this.now_offset>0 ? this.now_offset : this.show_limit;
				this.now_offset = 0;
				jQuery('#friend_content').html('');
				var txt = this.html_first(0,limit); // показыаем dtm список друзей который раньше был
				jQuery('#friend_content').append(txt);
				this.bind();
				this.check_more();
			} // view_all

			t.view_search = function()
			{
				jQuery('#friend_content').html('');
				jQuery('.flist_more').css({"display":"none"});
				var txt = this.html_search();
				jQuery('#friend_content').append(txt);
				this.bind();
			} // view_search

			t.check_more = function()
			{
				var len = this.data_count();
				if (this.now_offset < len)
				{
					jQuery('#oPopup .class_more_questions').css({"display":"block"});
				}
				else
				{
					jQuery('#oPopup .class_more_questions').css({"display":"none"});
				}
			} // check_more

			t.show_more = function()
			{
				var txt = this.html_first();
				jQuery('#friend_content').append(txt);
				this.bind();
				this.check_more();
			} // show more

			t.data_count = function() // возращает кол-во друзей из массива
			{
				var ii=0;
				for (var v in this.friends_data) 
				{
					var tt = this.friends_data[v];
					if (tt)
					{
						ii++;
					}
				}
				return ii;
			} // data_count

			// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
			// служебные
			// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

			t.vkResponse = function(data) // разбирает ответ от VK 
			{
				if (data)
				{
					for(var vv in data)
					{
						var tt = data[vv];

						if (typeof this.exclude[tt.uid] != 'undefined')
							continue;

						this.friends_data[tt.uid] = tt;
					}
				}
				this.show();
			} //

			t.show_selected_debug = function()
			{		
				var text='';
				for(var v in this.selected_data)
				{
					var temp = this.selected_data[v];
					if (temp)
					{
						text += "selected_data["+v+"] = {'uid':'"+temp.uid+"', 'first_name':'"+temp.first_name+"', 'last_name':'"+temp.last_name+"', 'photo':'"+temp.photo+"', 'photo_medium':'"+temp.photo_medium+"', 'photo_big':'"+temp.photo_big+"'};  \n";			
					}
				}
				jQuery('#ajax_bottom').html('<textarea style="width:400px;height:100px;">'+text+'</textarea>');
			}

			t.search = function(search_key)
			{
				this.search_data = {}
				search_key = search_key.toLowerCase();
				var re = new RegExp('('+search_key+')', 'i');
				
				for (var v in this.friends_data) 
				{
					var tt = this.friends_data[v];
					if (tt)
					{
						var text = ' '+tt.last_name + ' ' +tt.first_name;
						text = text.toLowerCase();		
						var s =text.search(re)

						if (s>0) 
						{
							this.search_data[tt.uid] = tt;
						}
						
					}
				}
				this.view_search();
			}

			// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
			// обработчики
			// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

			t.buttonYesClick = function() //"выбрать"
			{
				this.setup.button_yes.action(this.selected_data);
				to_remove();
			} // button_yes_click

			t.bind = function() // устанавливаем обработчики на клик и т.п.
			{
				var th	= this;
				// удаляем обработчики, если есть
				$(".flist_cell").unbind();

				var prev_check;
				$(".flist_cell").bind("click", function(event){
					var uid = this.id.replace('flist_cell',"");

					if (!jQuery(this).hasClass('flist_cell_on'))
					{
						jQuery(this).removeClass('flist_cell_over');
						jQuery(this).addClass('flist_cell_on');


						if (th.setup.multi == true)
						{
							//if (cl_friend.selected_data==false) { cl_friend.selected_data = [];}
							th.selected_data[uid] = th.friends_data[uid];
							_selected_count += 1;
						}
						else // если не стоит мульти выбор
						{
							th.selected_data = {};
							th.selected_data = th.friends_data[uid];
							if (prev_check) {th.selected_data[prev_check.replace('flist_cell',"")] = false;}
							jQuery('#'+prev_check).removeClass('flist_cell_on');
							_selected_count = 1;

							/** эмулируем как-буд-то мы дальше нажали применить */
							th.buttonYesClick();
							return false;
						}

						prev_check = this.id;
					}
					else
					{
						jQuery(this).removeClass('flist_cell_on');
						if (th.setup.multi  == true)
						{
							th.selected_data[uid] = false;
							_selected_count += 1;

						}
						else // если не стоит мульти выбор
						{
							th.selected_data = {};
							th.selected_data[uid] = false;
							_selected_count = 0;
						}
					}

					jQuery('#selected_count').html(_selected_count);
				}); // конец клика


				$(".flist_cell").bind("mouseover", function(event){
						if (!jQuery(this).hasClass('flist_cell_on'))
						jQuery(this).addClass('flist_cell_over');
				});


				$(".flist_cell").bind("mouseout", function(event){
						if (!jQuery(this).hasClass('flist_cell_on'))
						jQuery(this).removeClass('flist_cell_over');
				});	


				$(".flist_cell").bind("mouseout", function(event){
						if (!jQuery(this).hasClass('flist_cell_on'))
						jQuery(this).removeClass('flist_cell_over');
				});	

				$("#search_friend").unbind().live('keyup', function() 
				{
					if($(this).val() == '') { 
						if (th.view_all_flag == true) {
							th.view_all_flag	= false;
							th.view_all();
						}
						return false;
					}
					var search_key = $(this).val() ;
					if  (search_key == 'g123') {th.check_all();return false;}
					if  (search_key == 'g456') {th.check_456();return false;}
					if  (search_key == 'g10') {th.check_10();return false;}
					clearTimeout(_timer_search);
					_timer_search = setTimeout(function(p){ 
						th.search(search_key);
						th.view_all_flag	= true;
					},300);
				}); // конец поиска


				$("#search_friend").unbind().bind('click', function() // скрываем подсказку при клике по поиску
				{
					if (jQuery('#friend_search_hint').css('display')=='block')
					{
						jQuery('#friend_search_hint').css({"display":"none"});
					}
				}); 


			}

			// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
			// Html представление
			// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

			t.html_first = function(offset,limit) // показываем весь список
			{
				limit = limit || this.show_limit;
				offset = offset || this.now_offset;
				var ii=0;
				var txt='';
				var cls = '';
				for (var v in this.friends_data) 
				{
					var tt = this.friends_data[v];
					if (tt)
					{
						ii++;
						if (ii<=offset) continue;

						if (this.selected_data[tt.uid]) {cls = 'flist_cell flist_cell_on';} else {cls = 'flist_cell';}
						txt += this.html_f(tt,cls);

						if (ii-offset >= limit) break;
					}

				}
				this.now_offset = ii;
				return txt;
			} //

			t.html_selected = function() // показываем только выделенные элементы
			{
				var txt='';
				var cls = '';
				for (var v in this.friends_data) 
				{
					var tt = this.friends_data[v];
					if (tt)
					{
						if (this.selected_data[tt.uid]) {cls = 'flist_cell flist_cell_on';txt += this.html_f(tt,cls);} 
					}

				}
				return txt;
			} //

			t.html_search = function() // показываем только выделенные элементы
			{
				var txt='';
				var cls = '';
				for (var v in this.search_data) 
				{
					var tt = this.search_data[v];
					if (this.selected_data[tt.uid]) {cls = 'flist_cell flist_cell_on';} else {cls = 'flist_cell';}
					txt += this.html_f(tt,cls);
				}
				return txt;
			} //

			t.html_f = function(tt,cls)
			{
				var txt ='<div id="flist_cell'+tt.uid+'" class="'+cls+'">'+
						'	<div class="flist_border_wrap">'+
						'	  <div class="flist_wrap">'+
						'		<div class="flist_div">'+
						'		  <div class="flist_image">'+
						'			<img src="'+tt.photo+'">'+
						'		  </div>'+
						'		</div>'+
						'		<div class="flist_name">'+tt.first_name+' ' +tt.last_name+'</div>'+
						'	  </div>'+
						'	</div>'+
						'  </div>';
				return txt;
			}

			t.html_show_more = function()
			{
				var text = '<div class="read_more clear_fix pt10 pb10" onmouseover="SOCIAL.friends.handler.show_more();"><div></div></div>';
				return text;
			}

			t.html_submenu = function()
			{
				var text = 
				'<div class="tabs clear_fix" style="width:436px;">'+
				'	<div class="fl_l">'+
				'		<div class="input_back" style="margin-top: 0px; margin-left: 0px; margin-right: 0px; padding-top: 3px; padding-left: 3px; padding-right: 3px; width: 400px; height: 17px;">'+
				'			<div style="" id="friend_search_hint">'+
				'				Начните вводить имя друга'+
				'			</div>'+
				'		</div>'+
				'		<input type="text" class="text" id="search_friend" style="width: 424px; background-color: transparent; z-index: 91; position: relative;" placeholder="">'+
				'	</div>'+
				'</div>';

				return text;
			} // html_submenu;

			return t;
		} // 
			
		/** отдаем демо список друзей */
		t.getDemo	= function() {
			var demo = {};
			demo.response = [];
			demo.response[0] = {'uid':'187541','sex':1, 'first_name':'Бык', 'last_name':'Фанерный', 'photo':'http://cs10273.vkontakte.ru/u187541/e_9dba4203.jpg', 'photo_medium':'http://cs10273.vkontakte.ru/u187541/b_616edc92.jpg', 'photo_big':'http://cs10273.vkontakte.ru/u187541/a_26440879.jpg'};  
			demo.response[1] = {'uid':'696150','sex':1, 'first_name':'Евгений', 'last_name':'Яковлев', 'photo':'http://cs10349.vkontakte.ru/u696150/e_5249d11c.jpg', 'photo_medium':'http://cs10349.vkontakte.ru/u696150/b_456d8844.jpg', 'photo_big':'http://cs10349.vkontakte.ru/u696150/a_95d7a794.jpg'};  
			demo.response[2] = {'uid':'821732','sex':1, 'first_name':'Юрий', 'last_name':'Мясников', 'photo':'http://cs4851.vkontakte.ru/u821732/e_58886a8b.jpg', 'photo_medium':'http://cs4851.vkontakte.ru/u821732/b_b9bc6c20.jpg', 'photo_big':'http://cs4851.vkontakte.ru/u821732/a_5130cef1.jpg'};  
			demo.response[3] = {'uid':'1121773','sex':1, 'first_name':'Александр', 'last_name':'Осипов', 'photo':'http://cs9858.vkontakte.ru/u1121773/e_311b079c.jpg', 'photo_medium':'http://cs9858.vkontakte.ru/u1121773/b_57ea1b35.jpg', 'photo_big':'http://cs9858.vkontakte.ru/u1121773/a_e4edb6b2.jpg'};  
			demo.response[4] = {'uid':'187541','sex':1, 'first_name':'Бык', 'last_name':'Фанерный', 'photo':'http://cs10273.vkontakte.ru/u187541/e_9dba4203.jpg', 'photo_medium':'http://cs10273.vkontakte.ru/u187541/b_616edc92.jpg', 'photo_big':'http://cs10273.vkontakte.ru/u187541/a_26440879.jpg'};  
			demo.response[5] = {'uid':'696150','sex':1, 'first_name':'Евгений', 'last_name':'Яковлев', 'photo':'http://cs10349.vkontakte.ru/u696150/e_5249d11c.jpg', 'photo_medium':'http://cs10349.vkontakte.ru/u696150/b_456d8844.jpg', 'photo_big':'http://cs10349.vkontakte.ru/u696150/a_95d7a794.jpg'};  
			demo.response[6] = {'uid':'821732','sex':1, 'first_name':'Юрий', 'last_name':'Мясников', 'photo':'http://cs4851.vkontakte.ru/u821732/e_58886a8b.jpg', 'photo_medium':'http://cs4851.vkontakte.ru/u821732/b_b9bc6c20.jpg', 'photo_big':'http://cs4851.vkontakte.ru/u821732/a_5130cef1.jpg'};  
			demo.response[7] = {'uid':'1121773','sex':1, 'first_name':'Александр', 'last_name':'Осипов', 'photo':'http://cs9858.vkontakte.ru/u1121773/e_311b079c.jpg', 'photo_medium':'http://cs9858.vkontakte.ru/u1121773/b_57ea1b35.jpg', 'photo_big':'http://cs9858.vkontakte.ru/u1121773/a_e4edb6b2.jpg'};  
			demo.response[8] = {'uid':'187541','sex':1, 'first_name':'Бык', 'last_name':'Фанерный', 'photo':'http://cs10273.vkontakte.ru/u187541/e_9dba4203.jpg', 'photo_medium':'http://cs10273.vkontakte.ru/u187541/b_616edc92.jpg', 'photo_big':'http://cs10273.vkontakte.ru/u187541/a_26440879.jpg'};  
			demo.response[9] = {'uid':'696150','sex':1, 'first_name':'Евгений', 'last_name':'Яковлев', 'photo':'http://cs10349.vkontakte.ru/u696150/e_5249d11c.jpg', 'photo_medium':'http://cs10349.vkontakte.ru/u696150/b_456d8844.jpg', 'photo_big':'http://cs10349.vkontakte.ru/u696150/a_95d7a794.jpg'};  
			demo.response[10] = {'uid':'821732','sex':1, 'first_name':'Юрий', 'last_name':'Мясников', 'photo':'http://cs4851.vkontakte.ru/u821732/e_58886a8b.jpg', 'photo_medium':'http://cs4851.vkontakte.ru/u821732/b_b9bc6c20.jpg', 'photo_big':'http://cs4851.vkontakte.ru/u821732/a_5130cef1.jpg'};  
			demo.response[11] = {'uid':'1121773','sex':1, 'first_name':'Александр', 'last_name':'Осипов', 'photo':'http://cs9858.vkontakte.ru/u1121773/e_311b079c.jpg', 'photo_medium':'http://cs9858.vkontakte.ru/u1121773/b_57ea1b35.jpg', 'photo_big':'http://cs9858.vkontakte.ru/u1121773/a_e4edb6b2.jpg'};  
			demo.response[12] = {'uid':'187541','sex':1, 'first_name':'Бык', 'last_name':'Фанерный', 'photo':'http://cs10273.vkontakte.ru/u187541/e_9dba4203.jpg', 'photo_medium':'http://cs10273.vkontakte.ru/u187541/b_616edc92.jpg', 'photo_big':'http://cs10273.vkontakte.ru/u187541/a_26440879.jpg'};  
			
			for (var a=1;a<=400;a++) {
				var temp	= clone(demo.response[mt_rand(0,12)]);
				temp.uid	= a;
				demo.response.push(temp);
			}
			
			return demo.response;
		}
		
		/** вызываем окно приглашения для друзей */
		t.inviteBox	= function() {
			alert('SOCIAL.inviteBox');
			return false;
			VK.callMethod('showInviteBox');
		}
		
		/** показываем окно выбора друзей. После выбора друга возвращает его id - в функция after */
		t.showBox	= function(config) {
			alert('SOCIAL.showBox');
			return false;
			
			this.handler.set({
				title		:typeof config.title != 'undefined' ? config.title : 'Выберите друга',
				multi		:false,
				button_yes	:{title:'Выбрать',action:function(data) {if (typeof config.after!= 'undefined' ) {config.after(data);}to_remove();}}
			});
			
			if (typeof config.exclude!='undefined')
				this.handler.exclude	= config.exclude;
			else 
				this.handler.exclude	= [];
			
			/** show  */
			this.handler.start();
		}
		
		/** получаем список друзей кто уже установил это приложение из твоих друзей */
		t.getInApp	= function(after) {
			alert('SOCIAL.getInApp');
			return false;
			
			if (SERVER_OS == 'local') {
				var bb	= ["10000","169953","279695","452518","548301","1410633","1540319","1777629","1895834","2285650","2906680","3691975","3768870","3830880","3849180","4286609","4397275","6143609","6259107","6434783","6609719","6674166","7506208","7507211","7987311","8696054","9094628","9434945","9438952","9544564","9745570","10005495","10431029","10439407","10616422","11039478","11073019","11484261","11874830","12125935","12445702","13633966","13969948","14443845","15107590","15592730","16657355","16903325","18086743","18212878","19459423","20746706","20870728","20880102","22880705","23106410","23196318","23290340","23602539","23953430"];
				var output	= [];
				for (var i in bb) {
					if (bb[i]!=VK_ID)
						output.push(bb[i]);
				}

				return after(output);
			}
			
			if (SERVER_OS == 'vk') {
				/** вызываем из VK */
				VK.api(  
					'friends.getAppUsers',{},
					function(data) {
						after(data.response);
					}
				);
			}
		}
		
		/** пригласить друга */
		t.inviteListAndPostWall	= function() {
			log('inviteListAndPostWall...');
			
			if (SERVER_OS == 'vk' || SERVER_OS == 'local') {
				this.postFriendWall({
					'image_id'	: 'invite_friends_rand',
					'stat'		: 'invite_friend',
					'message'	: g('global.vk_invite_friend_main')
				});
			}
			
			/** */
			if (SERVER_OS == 'ok') {
				GLOBAL.set(GLOBAL_GET_FAPI_CONFIRM,function(data) {
					/** отправляем для статистики пополнения денег на сервер */
					API.call('service.statTell',{'key':'invite_friend'});
				});
				FAPI.UI.showInvite(g('global.ok_invite_friend'), 'customAttr=customValue');
			}
		}
		
		/** публикуем у друга на стене */
		t.postFriendWall	= function(info) {
			alert('SOCIAL.postFriendWall');
			return false;
			
			SOCIAL.friends.showBox({
				'after'		: function(data) {
					//log(data);
					info.stat	= info.stat || 'friend_other';
					info.after	= info.after || function(){};
					info.reciver_id	= data.uid;
					_postImageOnWall(info);
				}
			});
		}
		
		/** публикуем у себя на стене */
		t.postMyWall		= function(info) {
			info.stat	= info.stat || 'other';
			info.after	= info.after || function(){};
			_postOkWall(info);
		}
		
		/** публикуем у себя на стене */
		t.postWall		= function(info) {
			info.stat	= info.stat || 'other';
			info.after	= info.after || function(){};
			_postImageOnWall(info);
		}
		
		/**
		 *	----------------------------------------------------
		 *			PROTECTED 
		 *	----------------------------------------------------
		 **/
		
		function _postOkWall(dd) {
			var ok	= function(r) {
				if (typeof dd.stat != 'undefined' && dd.stat!='' && dd.stat!=false) {
					// отправляем статистику на сервер 
					API.call('service.statTell',{'key':dd.stat});
				}

				/** откаты, кляксыб и фиксация */
				if (typeof dd.need_blot != 'undefined' && dd.need_blot == true) {
					API.call('blot.statBlot',{'post_id':1,'blot_type':dd.blot_type},function(){
						bRemove();
						lAlert(g('location.blot_stat_save_ok'));
					});
				} else {
					bOk(g('global.vk_social_post_me'));
				}

				/** после - выполняем действия */
				if (typeof dd.after != 'undefined') {
					dd.after();
				}
			}
			
			var data	= dd;
			data.data	= GLOBAL.data;
			GLOBAL.set(GLOBAL_GET_FAPI_CONFIRM,function() {
					API.call('ok.postOkWall',data,ok,function(r) {
						bAlert(g('error.ok_'+r.code));
					});
				});
			FAPI.UI.showPermissions("['PHOTO CONTENT']");
		}
		
		/** Не работает. Из контакта - устаревшая */
		/** разместить информацию на стене - наследие контакта. */
		function _postImageOnWall(dd) {
			/** подготавливаем данные для отправки */
			
//			image_id,reciver_id,message,stat,after
//			var dd	= {};
//			dd.message	= message;
//			dd.reciver_id	= reciver_id;
//			dd.image_id	= image_id;
//			dd.stat		= stat;

			/** 
			* процесс такой: 
			* 1. Получаем у ВК адресс для загрузки фоток
			* 2. Отсылаем адресс и и общую информацию об оценках на наш сервер
			* 3. Загружаем сгенерированную картинку в ВК
			* 4. Возращаем данные для attachent в формате json
			**/
			var handler	= function(dd) {
				var t			= this;
				t.dd			= dd;
				t.attachment		= [];
				t.responseServerData	= {}; // наш ответ от сервера

				/** получаем данные для загрузки данных на сервер из контакта */
				t.getUrlFromVk		= function() {
					var th	= this;

					if (SERVER_OS == 'local') {
						this.sendDataToServer('http://url_to_upload.demo');
						return false;
					}

					VK.api(  
						'photos.getWallUploadServer',  
						{ 
							'uid': th.dd.reciver_id
						},  
						function(dd) {
							if (typeof dd.response != 'undefined') {
								if (typeof dd.response.upload_url != 'undefined')
								{
									th.sendDataToServer(dd.response.upload_url);
								} else {
									somethingError('VK error: photos.getWallUploadServer()');
								}
							} else {
								somethingError('VK error: photos.getWallUploadServer()');
							}
						}
					);
				}

				/** грузим к нам на серверер */
				t.sendDataToServer	= function(url) {
					var th		= this;
					th.dd.url	= url;
					API.call('social.vkUpload',th.dd,th.responseServer,somethingError);
				}

				/** jndtn jn yfituj cthdthf */
				t.responseServer	= function(rsData) {
					rsData				= rsData || this.responseServerData;
					this.responseServerData		= rsData;
					/** 
					* 'status'	= 'ok' | 'need_upload'
					* 'dd'	= ''	данные для отправки уже на стену \ либо для загрузки фотки и получения о ней данных
					**/

					if (SERVER_OS == 'local') {
						this.report();
						return false;
					}

					var th	= this;
					var i	= 0;
					for(var a in rsData.data) {
						var info	= rsData.data[a];
						if (typeof info.status != 'undefined') {
							i++;
							if (typeof th.attachment[i] != 'undefined')
								continue;

							if (info.status=='need_upload') {
								//log('need_upload');
								th.needUpload(info.data,i);
								return false;
							}
							else {
								//log('attachment');
								th.attachment[i]	= info.data;
							}
						}
					}

					th.publicOnWallVk();
					return false;
				}

				/** надо hash полученный от нашего сервера сконвертировать в фото объект */
				t.needUpload		= function(dd,i) {
					var th		= this;
					var a		= function() {
						VK.api(  
							'photos.saveWallPhoto',  
							{  
								'server'	: dd.server,
								'photo'		: dd.photo,
								'hash'		: dd.hash
							},  
							function(dd) {
								if (typeof dd.response != 'undefined') {
									if (typeof dd.response[0].id != 'undefined')
									{
										//log(dd.response[0].id);
										th.attachment[i]	= dd.response[0].id;
										//post('gifts','updategiftsvkdd',{ 'id':dd.response[0].id,'gift_id':gift_id});
										th.responseServer();
										return true;
									} else {
										th.attachment[i]	= '';
										th.responseServer();
										return false;
										//somethingError();
									}
								} else {
									//somethingError();
									th.attachment[i]	= '';
									th.responseServer();
									return false;
								}

								th.responseServer();
							}
						);
					}

					a();
					return false;
				}

				/** когда все готово - публикуем на стену */
				t.publicOnWallVk	= function() {
					var th	= this;
					VK.api(  
						'wall.post',  
						{  
							'owner_id'	: th.dd.reciver_id,
							'message'	: th.dd.message,
							'attachments'	: implode(",",th.attachment)
						},  
						function(dd) {
							if (typeof dd.response != 'undefined') {
								if (typeof dd.response.post_id != 'undefined')
								{
									th.report(dd.response.post_id);
								}
							}
						}
					);
				}

				/** */
				t.start			= function() {
					var th		= this;
					th.getUrlFromVk();
				}

				/** уведомленмя сервер об успешном приглашении, а пользователя что его другу ушла заявка  */
				t.report		= function(post_id) {
					var th	= this;
					if (th.dd.reciver_id == VK_ID)
						bOk(g('global.vk_social_post_me'));
					else
						bOk(g('global.vk_social_invite_ok'));
					
					if (typeof th.dd.stat != 'undefined' && th.dd.stat!='' && th.dd.stat!=false) {
						// отправляем статистику на сервер 
						API.call('service.statTell',{'key':th.dd.stat});
					}
					
					/** откаты, кляксыб и фиксация */
					if (typeof th.dd.need_blot != 'undefined' && th.dd.need_blot == true) {
						API.call('blot.statBlot',{'post_id':post_id,'blot_type':th.dd.blot_type},function(){
							bRemove();
							lAlert(g('location.blot_stat_save_ok'));
						});
					}
					
					/** после - выполняем действия */
					if (typeof after != 'undefined') {
						after();
					}
				}

				/** end */
				return t;
			}

			return false;
			
			alert('SOCIAL._postImageOnWall');
			return false;
			
			/** запускаем локальный обработчик */
			var h	= handler(dd);
			h.start();
		}
		
		
		return t;
	}
	
	/** базовая информация из соц сети */
	t.info		= infoHandler(t);
	function infoHandler(self) {
		var t	= {
			'self'	: self
		};
		
		/** возвращает имя, фамилию и т.п */
		t.getMain	= function(after) {
			var output	= {
				'name'	: '[soc] ' + PLAYER.profile.getInfo('name'),
				'photo'	: ADATA_URL + '/avatars/i' + zorro(PLAYER.profile.getInfo('avatar')) + '.jpg',
				'sex'	: 0
			};
			
			if (SERVER_OS == 'local') {
				return after(output);
			}
			
			if (SERVER_OS == 'vk') {
				/** -- -- */
				VK.api(  
					'users.get',  
					{  
						'uids': VK_ID,
						'fields' : 'sex, first_name, last_name, photo'
					},
					function(data) {
						var res		= data.response;
						output.photo	= res[0].photo;
						output.name	= res[0].first_name + ' ' + res[0].last_name;
						output.sex	= res[0].sex;

						after(output);
					}
				);
			}
		}
		
		/** устанавливаем звначение в левом меню */
		t.setCounter	= function(value) {
			if (SERVER_OS != 'vk') {
				return ;
			}
			
			VK.api('setCounter',  
				{  
					'counter': value
				}
			);
				
			VK.api('setNameInMenu',  
				{  
					'name': 'Ботва Онлайн'
				}
			);	
		}
		
		/** проверяем ссылку на приложение в меню слева */
		t.checkLeft	= function(after) {
			this.wellcome.add({'need_settings' : [256]}).start(after);
		}
		
		/** проверяем настройки приложения */
		t.wellcome	= wellcomeHandler(t);
		function wellcomeHandler(self) {
			var t	= {
				self		: self,
				need_settings	: self.self.conf.app_settings,
				after		: function() {}
			};			

			t.add	= function(config) {
				if (typeof config.need_settings!= 'undefined') {
					t.need_settings	= config.need_settings;
				}
				
				return this;
			}

			/** кликнули по кнопке, проверяем настройки  */
			t.start	= function(after) {
				var th		= this;
				
				if (typeof after !='undefined')
					this.after	= after;
				
				if (SERVER_OS == 'local' || SERVER_OS == 'ok')
					return this.after();

				_addApp();
			}

			
			/**
			 * -----------------------------------------------------
			 *			PROTECTED
			 * -----------------------------------------------------
			 **/
			
			/** добавляем приложение */
			function _addApp() {
				var th	= t;
				VK.callMethod('showInstallBox');
				VK.addCallback('onApplicationAdded', function(){			
					/** если приложение установлено уже - проверяем настройки */
					VK.api('getUserSettings',{}, function(app_set) {
						if (_checkApiSettings(app_set.response))
						{
							return t.after();
						} else {
							_changeSettings();
						}
					});
					
				});
			}
			
			/** изменяем настройки для приложения  */
			function _changeSettings() {
				var th	= t;
				VK.callMethod('showSettingsBox',_getSettingsBit());
				VK.addCallback('onSettingsChanged', function(app_set){
					//log(app_set);
					if (_checkApiSettings(app_set))
					{
						return t.after();
					} else {
						//log('api_settings_error_msg');
						//bAlert(g('error.vk_app_settings_error_msg'));
						lAlert({
							'message'	: g('error.vk_app_settings_error_msg'),
							'action'	: function() {
								setTimeout(function(){
									SOCIAL.info.wellcome.start(SOCIAL.info.wellcome.after);
								},3000);
							}
						});
					}
				});
			}
			
			/** возращает необходимую битовую маску для приложения */
			function _getSettingsBit() {
				var bit	= 0;
				for(var a in t.need_settings) {
					bit += parseInt(t.need_settings[a]);
				}
				return bit;
			}
			
			/** проверяем настройки которые нам вернули */
			function _checkApiSettings(app_set) {
				for(var a in t.need_settings) {
					if (!(parseInt(app_set) & parseInt(t.need_settings[a])) ) {
						//log('vK_set_app ' + app_set + ' - bit ' + t.need_settings[a]);
						//log(app_set);
						return false;
					}
				}
				return true;
			}
			
			return t; // wellcome_handler
		}
		
		t.checkPost	= function(post_id,after) {
			if (SERVER_OS == 'local') {
				return after(1);
			}
			
			/** -- -- */
			VK.api(  
				'wall.getById',  
				{  
					'posts': VK_ID + '_' + post_id
				},
				function(data) {
					var response	= data.response;
					var res = 0;
					if (typeof response[0]!='undefined' && typeof response[0]['id']!='undefined' && response[0]['id'] == post_id) 
						res = 1;
					
					after(res);
				}
			);
		}
		
		return t;
	}
	
	t.service	= serviceHandler(t)
	function serviceHandler(self) {
		var t	= {
			self	: self
		}
		
		/** обновляем онлайн друзей кто есть в приложении */
		t.updateFriendOnline	= function() {
			if (SERVER_OS != 'vk')
				return false;
			
			/** если недавно проверяли */
			var tt = getSettings(JS_SETTINGS_UPDATE_ONLINE_FRIENDS,0);
			if (!DEV_SERVER && parseInt(tt) > parseInt(time()-600))
				return false;
			
			setSettings(JS_SETTINGS_UPDATE_ONLINE_FRIENDS,time());
			/** получаем список друзей кто он лайн */
			VK.api('friends.getOnline',{}, function(r) {
					var list	= typeof r.response != 'undefined' ? r.response : [];
					var all		= {};
					var i		= 0;
					for (i in list) {
						var vk_id	= list[i];
						all['i'+vk_id]	= vk_id;
					}
					
					if (i == 0)
						return;
					
					/** кто в приложении */
					VK.api('friends.getAppUsers',{}, function(r) {
						var list	= typeof r.response != 'undefined' ? r.response : [];
						var need	= [];
						for (var i in list) {
							var key = list[i];
							if (typeof all['i'+key]!= 'undefined') {
								need.push(key);
							}
						}
						
						
						if (count(need)<1)
							return false;

						var need_txt	= need.join(',');
						/**  получаем инфрмацию о друзьях */
						VK.api('users.get',{uids:need_txt,fields:'uid,first_name,last_name,sex'}, function(r) {
							var list	= typeof r.response != 'undefined' ? r.response : [];
							API.call('service.updateFriendOnline',{'data':list});
						});
					});
				}
			);
		
		}
		
		return t;
	}
	return t;
}

/** 
 *-------------------------------------------------------------------   
 * Отвечает за всплытие popup после покупки с предлоежнием разместить на стену, 
 * а также обрабатывает все социальные функции друзей, постинга на стену и т.п.
 *-------------------------------------------------------------------   
 **/
function mirSocialHandler() {
	var t	= {
		conf	: {
			app_settings	: [
				'1',	// Пользователь разрешил отправлять ему уведомления. 
				'2',	// Доступ к друзьям. 
				'4',	// Доступ к фотографиям. 
			//	'256',	// Добавление ссылки на приложение в меню слева. 
			//	'1024'	// Доступ к статусам пользователя. 
			]
		}
	};
	
	
	t.tell		= tellHandler(t);
	function tellHandler(self) {
		var t	= {};
		t.self	= self;
				
		/** рассказать у себя на стене о своей ссылкe */
		t.tellAboutMe		= function() {
			var data	= {
				'image_id'	: 'tell_about_me',
				'stat'		: 'about_me',
				'message'	: g('global.vk_tell_about_me') + PLAYER.profile.getLink()
			}
			
			if (PLAYER.cache.get(JS_CACHE_CAN_BLOT)==1) {
				data['need_blot']	= true;
				data['blot_type']	= 'standart';
			}
			
			SOCIAL.friends.postMyWall(data);
		}
		
		/** OLD рассказать у себя на стене о своеем бое */
		t.tellAboutFightLog	= function(log_id) {
			var data	= {
				'image_id'	: 'tell_about_fight_log',
				'stat'		: 'about_fight',
				'message'	: g('global.vk_tell_fight')  + APP_URL + '#fight' + log_id
			};
			
			if (PLAYER.cache.get(JS_CACHE_CAN_BLOT)==1) {
				data['need_blot']	= true;
				data['blot_type']	= 'standart';
			}
			
			SOCIAL.friends.postMyWall(data);
		}
		
		/** рассказать у себя на стене о своеем бое */
		t.tellFightLog		= function(info) {
			info['image_id']	= 'tell_fight_log';
			info['stat']		= 'about_fight';
			//info['message']		= g('global.vk_tell_fight')  + APP_URL + '#fight' + info.log_id,
			info['message']		= BOTVA_URL + 'fight' + info.log_id;
			
			if (PLAYER.cache.get(JS_CACHE_CAN_BLOT)==1) {
				info['need_blot']	= true;
				info['blot_type']	= 'standart';
			}
			
			SOCIAL.friends.postMyWall(info);
		}
		
		/** рассказать у себя на стене о levelup */
		t.tellAboutLevelUp	= function() {
			var data	= {
				'image_id'	: 'tell_about_levelup_' + PLAYER.profile.getInfo('level'),
				'stat'		: 'about_levelup',
				'message'	: PLAYER.profile.getInfo('level') + g('global.vk_tell_level_up') + "\n" + BOTVA_URL + 'up'+PLAYER.profile.getInfo('user_id') + '_' + PLAYER.profile.getInfo('level')
			};
			
			if (PLAYER.cache.get(JS_CACHE_CAN_BLOT)==1) {
				data['need_blot']	= true;
				data['blot_type']	= 'standart';
			}
			
			SOCIAL.friends.postMyWall(data);
		}
		
		/** рассказать на стене о новой вещи*/
		t.tellAboutItem		= function(item_id) {
			SOCIAL.friends.postMyWall({
				'image_id'	: 'tell_item_' + item_id,
				'stat'		: 'about_item',
				'after'		: function() {
					API.call('profile.getBribe',{'key':item_id},function(r){
						// ok
						bOk(g('global.bribe_ok'));
					},function(r) {
						bAlert(g('error.profile_'+r.code));
					});
					
					setSettings(JS_SETTINGS_TELL_ABOUT_ITEM,'1');
					ACTIONS.mail.main.show();
				},
				'message'	: g('global.vk_tell_item') + "\n" + PLAYER.profile.getLink()
			});
		}
		return t;
	}
	
	t.friends	= friendsHandler(t);
	function friendsHandler(self) {
		var t	= {
			'self'	: self
		}
			
		/** 
		 * главный обработчик друзей из ВК. Старый класс - начала берет в 2008-м 
		 * по мере доработки - будет рефакториться
		 **/
		t.handler	= fHandler(t);
		function fHandler(self)
		{
			var t = {
				'self'	: self
			};
			
			var _selected_count	= 0;
			var _timer_search	= 0;
			
			t.setup		= {multi:false,title:"",bottom_left:"",submenu:false,button_yes:false};
			t.friends_data	= []; // массив с друзьями пользователя - получам его с VK 
			t.exclude	= [];
			t.view_all_flag	= true;

			t.now_offset	= 0; // опции показа друзей
			t.show_limit	= 150;
			t.selected_data;
			t.search_data	= {};

			// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
			// Методы
			// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

			t.set	= function(param) // задаем настройки для окна друзей
			{
				if (param.multi) this.setup.multi = param.multi;
				if (param.title) this.setup.title = param.title;
				if (param.button_yes) this.setup.button_yes = param.button_yes;
			} // set

			/** единственная точка входа в класс */
			t.start	= function() {
				if (count(this.friends_data)==0) {
					this.getFriends();
				} else {
					this.show();
				}
			}

			/** получаем друзей */
			t.getFriends	 = function()
			{	
				var th	= this;
				if (SERVER_OS == 'vk') {
					var th	= this;
						VK.api(  
							'friends.get',  
							{  
							'uid': VK_ID,
							'fields' : 'uid, sex, first_name, last_name, photo, photo_medium, photo_big'
							},
							function(data) {
								th.vkResponse(data.response);
							}
						);
		//			}

				} else {
					this.vkResponse(this.self.getDemo());
				}
			} // get_friend_demo

			t.show = function() // показываем форму
			{
				var th = this;

				this.now_offset = 0;
				_selected_count = 0;
				this.selected_data = {};
				var txt = this.html_first();
				var show_more_txt = this.html_show_more();
				var sub_menu = this.html_submenu();

				var content	= "<div id='friend_top_sub_menu' class='pt6 pb6 pl8 pr10 w430'>" +sub_menu+ "</div>" 
					+ "<div style='overflow:auto;height:420px;padding:3px;'><div class='mt8 clear_fix' id='friend_content'>"+txt+"</div><div id='after_friend_content'>"+show_more_txt+"</div></div>"

				var pp	= oPopup();
		//		pp.set({width:481,height:255});
				pp.set({width:485});
				pp.set({title:this.setup.title});
				pp.set({'content': content});
				pp.show();
				this.bind();
				this.check_more();
			} // show

		
			t.view_all = function()
			{
				var limit = 0;
				limit = this.now_offset>0 ? this.now_offset : this.show_limit;
				this.now_offset = 0;
				jQuery('#friend_content').html('');
				var txt = this.html_first(0,limit); // показыаем dtm список друзей который раньше был
				jQuery('#friend_content').append(txt);
				this.bind();
				this.check_more();
			} // view_all

			t.view_search = function()
			{
				jQuery('#friend_content').html('');
				jQuery('.flist_more').css({"display":"none"});
				var txt = this.html_search();
				jQuery('#friend_content').append(txt);
				this.bind();
			} // view_search

			t.check_more = function()
			{
				var len = this.data_count();
				if (this.now_offset < len)
				{
					jQuery('#oPopup .class_more_questions').css({"display":"block"});
				}
				else
				{
					jQuery('#oPopup .class_more_questions').css({"display":"none"});
				}
			} // check_more

			t.show_more = function()
			{
				var txt = this.html_first();
				jQuery('#friend_content').append(txt);
				this.bind();
				this.check_more();
			} // show more

			t.data_count = function() // возращает кол-во друзей из массива
			{
				var ii=0;
				for (var v in this.friends_data) 
				{
					var tt = this.friends_data[v];
					if (tt)
					{
						ii++;
					}
				}
				return ii;
			} // data_count

			// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
			// служебные
			// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

			t.vkResponse = function(data) // разбирает ответ от VK 
			{
				if (data)
				{
					for(var vv in data)
					{
						var tt = data[vv];

						if (typeof this.exclude[tt.uid] != 'undefined')
							continue;

						this.friends_data[tt.uid] = tt;
					}
				}
				this.show();
			} //

			t.show_selected_debug = function()
			{		
				var text='';
				for(var v in this.selected_data)
				{
					var temp = this.selected_data[v];
					if (temp)
					{
						text += "selected_data["+v+"] = {'uid':'"+temp.uid+"', 'first_name':'"+temp.first_name+"', 'last_name':'"+temp.last_name+"', 'photo':'"+temp.photo+"', 'photo_medium':'"+temp.photo_medium+"', 'photo_big':'"+temp.photo_big+"'};  \n";			
					}
				}
				jQuery('#ajax_bottom').html('<textarea style="width:400px;height:100px;">'+text+'</textarea>');
			}

			t.search = function(search_key)
			{
				this.search_data = {}
				search_key = search_key.toLowerCase();
				var re = new RegExp('('+search_key+')', 'i');
				
				for (var v in this.friends_data) 
				{
					var tt = this.friends_data[v];
					if (tt)
					{
						var text = ' '+tt.last_name + ' ' +tt.first_name;
						text = text.toLowerCase();		
						var s =text.search(re)

						if (s>0) 
						{
							this.search_data[tt.uid] = tt;
						}
						
					}
				}
				this.view_search();
			}

			// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
			// обработчики
			// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

			t.buttonYesClick = function() //"выбрать"
			{
				this.setup.button_yes.action(this.selected_data);
				to_remove();
			} // button_yes_click

			t.bind = function() // устанавливаем обработчики на клик и т.п.
			{
				var th	= this;
				// удаляем обработчики, если есть
				$(".flist_cell").unbind();

				var prev_check;
				$(".flist_cell").bind("click", function(event){
					var uid = this.id.replace('flist_cell',"");

					if (!jQuery(this).hasClass('flist_cell_on'))
					{
						jQuery(this).removeClass('flist_cell_over');
						jQuery(this).addClass('flist_cell_on');


						if (th.setup.multi == true)
						{
							//if (cl_friend.selected_data==false) { cl_friend.selected_data = [];}
							th.selected_data[uid] = th.friends_data[uid];
							_selected_count += 1;
						}
						else // если не стоит мульти выбор
						{
							th.selected_data = {};
							th.selected_data = th.friends_data[uid];
							if (prev_check) {th.selected_data[prev_check.replace('flist_cell',"")] = false;}
							jQuery('#'+prev_check).removeClass('flist_cell_on');
							_selected_count = 1;

							/** эмулируем как-буд-то мы дальше нажали применить */
							th.buttonYesClick();
							return false;
						}

						prev_check = this.id;
					}
					else
					{
						jQuery(this).removeClass('flist_cell_on');
						if (th.setup.multi  == true)
						{
							th.selected_data[uid] = false;
							_selected_count += 1;

						}
						else // если не стоит мульти выбор
						{
							th.selected_data = {};
							th.selected_data[uid] = false;
							_selected_count = 0;
						}
					}

					jQuery('#selected_count').html(_selected_count);
				}); // конец клика


				$(".flist_cell").bind("mouseover", function(event){
						if (!jQuery(this).hasClass('flist_cell_on'))
						jQuery(this).addClass('flist_cell_over');
				});


				$(".flist_cell").bind("mouseout", function(event){
						if (!jQuery(this).hasClass('flist_cell_on'))
						jQuery(this).removeClass('flist_cell_over');
				});	


				$(".flist_cell").bind("mouseout", function(event){
						if (!jQuery(this).hasClass('flist_cell_on'))
						jQuery(this).removeClass('flist_cell_over');
				});	

				$("#search_friend").unbind().live('keyup', function() 
				{
					if($(this).val() == '') { 
						if (th.view_all_flag == true) {
							th.view_all_flag	= false;
							th.view_all();
						}
						return false;
					}
					var search_key = $(this).val() ;
					if  (search_key == 'g123') {th.check_all();return false;}
					if  (search_key == 'g456') {th.check_456();return false;}
					if  (search_key == 'g10') {th.check_10();return false;}
					clearTimeout(_timer_search);
					_timer_search = setTimeout(function(p){ 
						th.search(search_key);
						th.view_all_flag	= true;
					},300);
				}); // конец поиска


				$("#search_friend").unbind().bind('click', function() // скрываем подсказку при клике по поиску
				{
					if (jQuery('#friend_search_hint').css('display')=='block')
					{
						jQuery('#friend_search_hint').css({"display":"none"});
					}
				}); 


			}

			// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
			// Html представление
			// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

			t.html_first = function(offset,limit) // показываем весь список
			{
				limit = limit || this.show_limit;
				offset = offset || this.now_offset;
				var ii=0;
				var txt='';
				var cls = '';
				for (var v in this.friends_data) 
				{
					var tt = this.friends_data[v];
					if (tt)
					{
						ii++;
						if (ii<=offset) continue;

						if (this.selected_data[tt.uid]) {cls = 'flist_cell flist_cell_on';} else {cls = 'flist_cell';}
						txt += this.html_f(tt,cls);

						if (ii-offset >= limit) break;
					}

				}
				this.now_offset = ii;
				return txt;
			} //

			t.html_selected = function() // показываем только выделенные элементы
			{
				var txt='';
				var cls = '';
				for (var v in this.friends_data) 
				{
					var tt = this.friends_data[v];
					if (tt)
					{
						if (this.selected_data[tt.uid]) {cls = 'flist_cell flist_cell_on';txt += this.html_f(tt,cls);} 
					}

				}
				return txt;
			} //

			t.html_search = function() // показываем только выделенные элементы
			{
				var txt='';
				var cls = '';
				for (var v in this.search_data) 
				{
					var tt = this.search_data[v];
					if (this.selected_data[tt.uid]) {cls = 'flist_cell flist_cell_on';} else {cls = 'flist_cell';}
					txt += this.html_f(tt,cls);
				}
				return txt;
			} //

			t.html_f = function(tt,cls)
			{
				var txt ='<div id="flist_cell'+tt.uid+'" class="'+cls+'">'+
						'	<div class="flist_border_wrap">'+
						'	  <div class="flist_wrap">'+
						'		<div class="flist_div">'+
						'		  <div class="flist_image">'+
						'			<img src="'+tt.photo+'">'+
						'		  </div>'+
						'		</div>'+
						'		<div class="flist_name">'+tt.first_name+' ' +tt.last_name+'</div>'+
						'	  </div>'+
						'	</div>'+
						'  </div>';
				return txt;
			}

			t.html_show_more = function()
			{
				var text = '<div class="read_more clear_fix pt10 pb10" onmouseover="SOCIAL.friends.handler.show_more();"><div></div></div>';
				return text;
			}

			t.html_submenu = function()
			{
				var text = 
				'<div class="tabs clear_fix" style="width:436px;">'+
				'	<div class="fl_l">'+
				'		<div class="input_back" style="margin-top: 0px; margin-left: 0px; margin-right: 0px; padding-top: 3px; padding-left: 3px; padding-right: 3px; width: 400px; height: 17px;">'+
				'			<div style="" id="friend_search_hint">'+
				'				Начните вводить имя друга'+
				'			</div>'+
				'		</div>'+
				'		<input type="text" class="text" id="search_friend" style="width: 424px; background-color: transparent; z-index: 91; position: relative;" placeholder="">'+
				'	</div>'+
				'</div>';

				return text;
			} // html_submenu;

			return t;
		} // 
			
		/** отдаем демо список друзей */
		t.getDemo	= function() {
			var demo = {};
			demo.response = [];
			demo.response[0] = {'uid':'187541','sex':1, 'first_name':'Бык', 'last_name':'Фанерный', 'photo':'http://cs10273.vkontakte.ru/u187541/e_9dba4203.jpg', 'photo_medium':'http://cs10273.vkontakte.ru/u187541/b_616edc92.jpg', 'photo_big':'http://cs10273.vkontakte.ru/u187541/a_26440879.jpg'};  
			demo.response[1] = {'uid':'696150','sex':1, 'first_name':'Евгений', 'last_name':'Яковлев', 'photo':'http://cs10349.vkontakte.ru/u696150/e_5249d11c.jpg', 'photo_medium':'http://cs10349.vkontakte.ru/u696150/b_456d8844.jpg', 'photo_big':'http://cs10349.vkontakte.ru/u696150/a_95d7a794.jpg'};  
			demo.response[2] = {'uid':'821732','sex':1, 'first_name':'Юрий', 'last_name':'Мясников', 'photo':'http://cs4851.vkontakte.ru/u821732/e_58886a8b.jpg', 'photo_medium':'http://cs4851.vkontakte.ru/u821732/b_b9bc6c20.jpg', 'photo_big':'http://cs4851.vkontakte.ru/u821732/a_5130cef1.jpg'};  
			demo.response[3] = {'uid':'1121773','sex':1, 'first_name':'Александр', 'last_name':'Осипов', 'photo':'http://cs9858.vkontakte.ru/u1121773/e_311b079c.jpg', 'photo_medium':'http://cs9858.vkontakte.ru/u1121773/b_57ea1b35.jpg', 'photo_big':'http://cs9858.vkontakte.ru/u1121773/a_e4edb6b2.jpg'};  
			demo.response[4] = {'uid':'187541','sex':1, 'first_name':'Бык', 'last_name':'Фанерный', 'photo':'http://cs10273.vkontakte.ru/u187541/e_9dba4203.jpg', 'photo_medium':'http://cs10273.vkontakte.ru/u187541/b_616edc92.jpg', 'photo_big':'http://cs10273.vkontakte.ru/u187541/a_26440879.jpg'};  
			demo.response[5] = {'uid':'696150','sex':1, 'first_name':'Евгений', 'last_name':'Яковлев', 'photo':'http://cs10349.vkontakte.ru/u696150/e_5249d11c.jpg', 'photo_medium':'http://cs10349.vkontakte.ru/u696150/b_456d8844.jpg', 'photo_big':'http://cs10349.vkontakte.ru/u696150/a_95d7a794.jpg'};  
			demo.response[6] = {'uid':'821732','sex':1, 'first_name':'Юрий', 'last_name':'Мясников', 'photo':'http://cs4851.vkontakte.ru/u821732/e_58886a8b.jpg', 'photo_medium':'http://cs4851.vkontakte.ru/u821732/b_b9bc6c20.jpg', 'photo_big':'http://cs4851.vkontakte.ru/u821732/a_5130cef1.jpg'};  
			demo.response[7] = {'uid':'1121773','sex':1, 'first_name':'Александр', 'last_name':'Осипов', 'photo':'http://cs9858.vkontakte.ru/u1121773/e_311b079c.jpg', 'photo_medium':'http://cs9858.vkontakte.ru/u1121773/b_57ea1b35.jpg', 'photo_big':'http://cs9858.vkontakte.ru/u1121773/a_e4edb6b2.jpg'};  
			demo.response[8] = {'uid':'187541','sex':1, 'first_name':'Бык', 'last_name':'Фанерный', 'photo':'http://cs10273.vkontakte.ru/u187541/e_9dba4203.jpg', 'photo_medium':'http://cs10273.vkontakte.ru/u187541/b_616edc92.jpg', 'photo_big':'http://cs10273.vkontakte.ru/u187541/a_26440879.jpg'};  
			demo.response[9] = {'uid':'696150','sex':1, 'first_name':'Евгений', 'last_name':'Яковлев', 'photo':'http://cs10349.vkontakte.ru/u696150/e_5249d11c.jpg', 'photo_medium':'http://cs10349.vkontakte.ru/u696150/b_456d8844.jpg', 'photo_big':'http://cs10349.vkontakte.ru/u696150/a_95d7a794.jpg'};  
			demo.response[10] = {'uid':'821732','sex':1, 'first_name':'Юрий', 'last_name':'Мясников', 'photo':'http://cs4851.vkontakte.ru/u821732/e_58886a8b.jpg', 'photo_medium':'http://cs4851.vkontakte.ru/u821732/b_b9bc6c20.jpg', 'photo_big':'http://cs4851.vkontakte.ru/u821732/a_5130cef1.jpg'};  
			demo.response[11] = {'uid':'1121773','sex':1, 'first_name':'Александр', 'last_name':'Осипов', 'photo':'http://cs9858.vkontakte.ru/u1121773/e_311b079c.jpg', 'photo_medium':'http://cs9858.vkontakte.ru/u1121773/b_57ea1b35.jpg', 'photo_big':'http://cs9858.vkontakte.ru/u1121773/a_e4edb6b2.jpg'};  
			demo.response[12] = {'uid':'187541','sex':1, 'first_name':'Бык', 'last_name':'Фанерный', 'photo':'http://cs10273.vkontakte.ru/u187541/e_9dba4203.jpg', 'photo_medium':'http://cs10273.vkontakte.ru/u187541/b_616edc92.jpg', 'photo_big':'http://cs10273.vkontakte.ru/u187541/a_26440879.jpg'};  
			
			for (var a=1;a<=400;a++) {
				var temp	= clone(demo.response[mt_rand(0,12)]);
				temp.uid	= a;
				demo.response.push(temp);
			}
			
			return demo.response;
		}
		
		/** вызываем окно приглашения для друзей */
		t.inviteBox	= function() {
			alert('SOCIAL.inviteBox');
			return false;
			VK.callMethod('showInviteBox');
		}
		
		/** показываем окно выбора друзей. После выбора друга возвращает его id - в функция after */
		t.showBox	= function(config) {
			alert('SOCIAL.showBox');
			return false;
			
			this.handler.set({
				title		:typeof config.title != 'undefined' ? config.title : 'Выберите друга',
				multi		:false,
				button_yes	:{title:'Выбрать',action:function(data) {if (typeof config.after!= 'undefined' ) {config.after(data);}to_remove();}}
			});
			
			if (typeof config.exclude!='undefined')
				this.handler.exclude	= config.exclude;
			else 
				this.handler.exclude	= [];
			
			/** show  */
			this.handler.start();
		}
		
		/** получаем список друзей кто уже установил это приложение из твоих друзей */
		t.getInApp	= function(after) {
			alert('SOCIAL.getInApp');
			return false;
			
			if (SERVER_OS == 'local') {
				var bb	= ["10000","169953","279695","452518","548301","1410633","1540319","1777629","1895834","2285650","2906680","3691975","3768870","3830880","3849180","4286609","4397275","6143609","6259107","6434783","6609719","6674166","7506208","7507211","7987311","8696054","9094628","9434945","9438952","9544564","9745570","10005495","10431029","10439407","10616422","11039478","11073019","11484261","11874830","12125935","12445702","13633966","13969948","14443845","15107590","15592730","16657355","16903325","18086743","18212878","19459423","20746706","20870728","20880102","22880705","23106410","23196318","23290340","23602539","23953430"];
				var output	= [];
				for (var i in bb) {
					if (bb[i]!=VK_ID)
						output.push(bb[i]);
				}

				return after(output);
			}
			
			if (SERVER_OS == 'vk') {
				/** вызываем из VK */
				VK.api(  
					'friends.getAppUsers',{},
					function(data) {
						after(data.response);
					}
				);
			}
		}
		
		/** пригласить друга */
		t.inviteListAndPostWall	= function() {
			log('inviteListAndPostWall...');
			
			if (SERVER_OS == 'vk' || SERVER_OS == 'local') {
				this.postFriendWall({
					'image_id'	: 'invite_friends_rand',
					'stat'		: 'invite_friend',
					'message'	: g('global.vk_invite_friend_main')
				});
			}
			
			/** */
			if (SERVER_OS == 'ok') {
				FAPI.UI.showInvite(g('global.ok_invite_friend'), 'customAttr=customValue');
			}
		}
		
		
		
		/** публикуем у друга на стене */
		t.postFriendWall	= function(info) {
			alert('SOCIAL.postFriendWall');
			return false;
			
			SOCIAL.friends.showBox({
				'after'		: function(data) {
					//log(data);
					info.stat	= info.stat || 'friend_other';
					info.after	= info.after || function(){};
					info.reciver_id	= data.uid;
					_postImageOnWall(info);
				}
			});
		}
		
		/** публикуем у себя на стене */
		t.postMyWall		= function(info) {
			info.stat	= info.stat || 'other';
			info.after	= info.after || function(){};
			info.reciver_id	= VK_ID;
			_postImageOnWall(info);
		}
		
		/** публикуем у себя на стене */
		t.postWall		= function(info) {
			info.stat	= info.stat || 'other';
			info.after	= info.after || function(){};
			_postImageOnWall(info);
		}
		
		/**
		 *	----------------------------------------------------
		 *			PROTECTED 
		 *	----------------------------------------------------
		 **/
		
		/** разместить информацию на стене */
		function _postImageOnWall(dd) {
			/** подготавливаем данные для отправки */
			
//			image_id,reciver_id,message,stat,after
//			var dd	= {};
//			dd.message	= message;
//			dd.reciver_id	= reciver_id;
//			dd.image_id	= image_id;
//			dd.stat		= stat;

			/** 
			* процесс такой: 
			* 1. Получаем у ВК адресс для загрузки фоток
			* 2. Отсылаем адресс и и общую информацию об оценках на наш сервер
			* 3. Загружаем сгенерированную картинку в ВК
			* 4. Возращаем данные для attachent в формате json
			**/
			var handler	= function(dd) {
				var t			= this;
				t.dd			= dd;
				t.attachment		= [];
				t.responseServerData	= {}; // наш ответ от сервера

				/** получаем данные для загрузки данных на сервер из контакта */
				t.getUrlFromVk		= function() {
					var th	= this;

					if (SERVER_OS == 'local') {
						this.sendDataToServer('http://url_to_upload.demo');
						return false;
					}

					VK.api(  
						'photos.getWallUploadServer',  
						{ 
							'uid': th.dd.reciver_id
						},  
						function(dd) {
							if (typeof dd.response != 'undefined') {
								if (typeof dd.response.upload_url != 'undefined')
								{
									th.sendDataToServer(dd.response.upload_url);
								} else {
									somethingError('VK error: photos.getWallUploadServer()');
								}
							} else {
								somethingError('VK error: photos.getWallUploadServer()');
							}
						}
					);
				}

				/** грузим к нам на серверер */
				t.sendDataToServer	= function(url) {
					var th		= this;
					th.dd.url	= url;
					API.call('social.vkUpload',th.dd,th.responseServer,somethingError);
				}

				/** jndtn jn yfituj cthdthf */
				t.responseServer	= function(rsData) {
					rsData				= rsData || this.responseServerData;
					this.responseServerData		= rsData;
					/** 
					* 'status'	= 'ok' | 'need_upload'
					* 'dd'	= ''	данные для отправки уже на стену \ либо для загрузки фотки и получения о ней данных
					**/

					if (SERVER_OS == 'local') {
						this.report();
						return false;
					}

					var th	= this;
					var i	= 0;
					for(var a in rsData.data) {
						var info	= rsData.data[a];
						if (typeof info.status != 'undefined') {
							i++;
							if (typeof th.attachment[i] != 'undefined')
								continue;

							if (info.status=='need_upload') {
								//log('need_upload');
								th.needUpload(info.data,i);
								return false;
							}
							else {
								//log('attachment');
								th.attachment[i]	= info.data;
							}
						}
					}

					th.publicOnWallVk();
					return false;
				}

				/** надо hash полученный от нашего сервера сконвертировать в фото объект */
				t.needUpload		= function(dd,i) {
					var th		= this;
					var a		= function() {
						VK.api(  
							'photos.saveWallPhoto',  
							{  
								'server'	: dd.server,
								'photo'		: dd.photo,
								'hash'		: dd.hash
							},  
							function(dd) {
								if (typeof dd.response != 'undefined') {
									if (typeof dd.response[0].id != 'undefined')
									{
										//log(dd.response[0].id);
										th.attachment[i]	= dd.response[0].id;
										//post('gifts','updategiftsvkdd',{ 'id':dd.response[0].id,'gift_id':gift_id});
										th.responseServer();
										return true;
									} else {
										th.attachment[i]	= '';
										th.responseServer();
										return false;
										//somethingError();
									}
								} else {
									//somethingError();
									th.attachment[i]	= '';
									th.responseServer();
									return false;
								}

								th.responseServer();
							}
						);
					}

					a();
					return false;
				}

				/** когда все готово - публикуем на стену */
				t.publicOnWallVk	= function() {
					var th	= this;
					VK.api(  
						'wall.post',  
						{  
							'owner_id'	: th.dd.reciver_id,
							'message'	: th.dd.message,
							'attachments'	: implode(",",th.attachment)
						},  
						function(dd) {
							if (typeof dd.response != 'undefined') {
								if (typeof dd.response.post_id != 'undefined')
								{
									th.report(dd.response.post_id);
								}
							}
						}
					);
				}

				/** */
				t.start			= function() {
					var th		= this;
					th.getUrlFromVk();
				}

				/** уведомленмя сервер об успешном приглашении, а пользователя что его другу ушла заявка  */
				t.report		= function(post_id) {
					var th	= this;
					if (th.dd.reciver_id == VK_ID)
						bOk(g('global.vk_social_post_me'));
					else
						bOk(g('global.vk_social_invite_ok'));
					
					if (typeof th.dd.stat != 'undefined' && th.dd.stat!='' && th.dd.stat!=false) {
						// отправляем статистику на сервер 
						API.call('service.statTell',{'key':th.dd.stat});
					}
					
					/** откаты, кляксыб и фиксация */
					if (typeof th.dd.need_blot != 'undefined' && th.dd.need_blot == true) {
						API.call('blot.statBlot',{'post_id':post_id,'blot_type':th.dd.blot_type},function(){
							bRemove();
							lAlert(g('location.blot_stat_save_ok'));
						});
					}
					
					/** после - выполняем действия */
					if (typeof after != 'undefined') {
						after();
					}
				}

				/** end */
				return t;
			}

			alert('SOCIAL._postImageOnWall');
			return false;
			
			/** запускаем локальный обработчик */
			var h	= handler(dd);
			h.start();
		}
		
		
		return t;
	}
	
	/** базовая информация из соц сети */
	t.info		= infoHandler(t);
	function infoHandler(self) {
		var t	= {
			'self'	: self
		};
		
		/** возвращает имя, фамилию и т.п */
		t.getMain	= function(after) {
			var output	= {
				'name'	: '[soc] ' + PLAYER.profile.getInfo('name'),
				'photo'	: ADATA_URL + '/avatars/i' + zorro(PLAYER.profile.getInfo('avatar')) + '.jpg',
				'sex'	: 0
			};
			
			if (SERVER_OS == 'local') {
				return after(output);
			}
			
			if (SERVER_OS == 'vk') {
				/** -- -- */
				VK.api(  
					'users.get',  
					{  
						'uids': VK_ID,
						'fields' : 'sex, first_name, last_name, photo'
					},
					function(data) {
						var res		= data.response;
						output.photo	= res[0].photo;
						output.name	= res[0].first_name + ' ' + res[0].last_name;
						output.sex	= res[0].sex;

						after(output);
					}
				);
			}
		}
		
		/** устанавливаем звначение в левом меню */
		t.setCounter	= function(value) {
			if (SERVER_OS != 'vk') {
				return ;
			}
			
			VK.api('setCounter',  
				{  
					'counter': value
				}
			);
				
			VK.api('setNameInMenu',  
				{  
					'name': 'Ботва Онлайн'
				}
			);	
		}
		
		/** проверяем ссылку на приложение в меню слева */
		t.checkLeft	= function(after) {
			this.wellcome.add({'need_settings' : [256]}).start(after);
		}
		
		/** проверяем настройки приложения */
		t.wellcome	= wellcomeHandler(t);
		function wellcomeHandler(self) {
			var t	= {
				self		: self,
				need_settings	: self.self.conf.app_settings,
				after		: function() {}
			};			

			t.add	= function(config) {
				if (typeof config.need_settings!= 'undefined') {
					t.need_settings	= config.need_settings;
				}
				
				return this;
			}

			/** кликнули по кнопке, проверяем настройки  */
			t.start	= function(after) {
				var th		= this;
				
				if (typeof after !='undefined')
					this.after	= after;
				
				if (SERVER_OS == 'local' || SERVER_OS == 'ok' || SERVER_OS == 'mir')
					return this.after();

				_addApp();
			}

			
			/**
			 * -----------------------------------------------------
			 *			PROTECTED
			 * -----------------------------------------------------
			 **/
			
			/** добавляем приложение */
			function _addApp() {
				var th	= t;
				VK.callMethod('showInstallBox');
				VK.addCallback('onApplicationAdded', function(){			
					/** если приложение установлено уже - проверяем настройки */
					VK.api('getUserSettings',{}, function(app_set) {
						if (_checkApiSettings(app_set.response))
						{
							return t.after();
						} else {
							_changeSettings();
						}
					});
					
				});
			}
			
			/** изменяем настройки для приложения  */
			function _changeSettings() {
				var th	= t;
				VK.callMethod('showSettingsBox',_getSettingsBit());
				VK.addCallback('onSettingsChanged', function(app_set){
					//log(app_set);
					if (_checkApiSettings(app_set))
					{
						return t.after();
					} else {
						//log('api_settings_error_msg');
						//bAlert(g('error.vk_app_settings_error_msg'));
						lAlert({
							'message'	: g('error.vk_app_settings_error_msg'),
							'action'	: function() {
								setTimeout(function(){
									SOCIAL.info.wellcome.start(SOCIAL.info.wellcome.after);
								},3000);
							}
						});
					}
				});
			}
			
			/** возращает необходимую битовую маску для приложения */
			function _getSettingsBit() {
				var bit	= 0;
				for(var a in t.need_settings) {
					bit += parseInt(t.need_settings[a]);
				}
				return bit;
			}
			
			/** проверяем настройки которые нам вернули */
			function _checkApiSettings(app_set) {
				for(var a in t.need_settings) {
					if (!(parseInt(app_set) & parseInt(t.need_settings[a])) ) {
						//log('vK_set_app ' + app_set + ' - bit ' + t.need_settings[a]);
						//log(app_set);
						return false;
					}
				}
				return true;
			}
			
			return t; // wellcome_handler
		}
		
		t.checkPost	= function(post_id,after) {
			if (SERVER_OS == 'local') {
				return after(1);
			}
			
			/** -- -- */
			VK.api(  
				'wall.getById',  
				{  
					'posts': VK_ID + '_' + post_id
				},
				function(data) {
					var response	= data.response;
					var res = 0;
					if (typeof response[0]!='undefined' && typeof response[0]['id']!='undefined' && response[0]['id'] == post_id) 
						res = 1;
					
					after(res);
				}
			);
		}
		
		return t;
	}
	
	t.service	= serviceHandler(t)
	function serviceHandler(self) {
		var t	= {
			self	: self
		}
		
		/** обновляем онлайн друзей кто есть в приложении */
		t.updateFriendOnline	= function() {
			if (SERVER_OS != 'vk')
				return false;
			
			/** если недавно проверяли */
			var tt = getSettings(JS_SETTINGS_UPDATE_ONLINE_FRIENDS,0);
			if (!DEV_SERVER && parseInt(tt) > parseInt(time()-600))
				return false;
			
			setSettings(JS_SETTINGS_UPDATE_ONLINE_FRIENDS,time());
			/** получаем список друзей кто он лайн */
			VK.api('friends.getOnline',{}, function(r) {
					var list	= typeof r.response != 'undefined' ? r.response : [];
					var all		= {};
					var i		= 0;
					for (i in list) {
						var vk_id	= list[i];
						all['i'+vk_id]	= vk_id;
					}
					
					if (i == 0)
						return;
					
					/** кто в приложении */
					VK.api('friends.getAppUsers',{}, function(r) {
						var list	= typeof r.response != 'undefined' ? r.response : [];
						var need	= [];
						for (var i in list) {
							var key = list[i];
							if (typeof all['i'+key]!= 'undefined') {
								need.push(key);
							}
						}
						
						
						if (count(need)<1)
							return false;

						var need_txt	= need.join(',');
						/**  получаем инфрмацию о друзьях */
						VK.api('users.get',{uids:need_txt,fields:'uid,first_name,last_name,sex'}, function(r) {
							var list	= typeof r.response != 'undefined' ? r.response : [];
							API.call('service.updateFriendOnline',{'data':list});
						});
					});
				}
			);
		
		}
		
		return t;
	}
	return t;
}

/** 
 *-------------------------------------------------------------------   
 *			ToolTip для вещей
 *-------------------------------------------------------------------   
 **/
function tooltipHandler() {
	var t		= {
		'path'	: {
			'main'		: '#tooltip',
			'content'	: '#tooltip .tooltip_body',
			'arrow'		: '#tooltip .tooltip_arrow'
		}
	};
	
	var _cache	= {
		'obj'		: {},
		'param'		: {},
		'timer_show'	: 0,
		'timer_hide'	: 0,
		'is_hide'	: true
	};
	
	/** 
	 * показывает tooltip, параметры: 
	 * {
	 *	'type'	: 'Тип записи (house,items,gifts,desc)'
	 *	'id'	: 'id записи',
	 *	'keep'	: 'позволять наводить мышкой',	true - по умолчанию
	 *	'extra'	: 'дополнительные параметры', {
	 *		'my'	: 'true' - моя ли вещь (надеть\снять, продлить сейфы)
	 *	}
	 * }
	 **/
	t.show		= function(obj,param) {
		if (_cache.obj == obj && _cache.is_hide == false) {
			clearTimeout(_cache['timer_hide']);
			return;
		}
		
		/** настройки по умолчанию */
		param.left	= param.left || 0;
		param.top	= param.top || 0;
		param.arrow_left= param.arrow_left || 0;
		
		_cache.obj	= obj;
		_cache.param	= param;
		
		/** сбрасываем таймеры */
		clearTimeout(_cache.timer_show);
		clearTimeout(_cache.timer_hide);
		
		_start();		// подготавливем
	}
	
	/** маленькие подсказки */
	t.hint		= function(obj,code,offset) {
		if (typeof offset == 'undefined') {
			offset	= {left:0,top:0,arrow_left:0};
		}
		
		if (typeof offset.left == 'undefined') {
			offset.left = 0;
		}
		
		if (typeof offset.top == 'undefined') {
			offset.top = 0;
		}
		
		if (typeof offset.arrow_left == 'undefined') {
			offset.arrow_left = 0;
		}
		
		this.show(obj,{'type':'hint','code':code,'left':offset.left,'top':offset.top,'arrow_left':offset.arrow_left});
	}
	
	/** скрываем tooltip, курсор ушел с блока obj  */
	t.hide		= function(force) {
		if (force) {
			_hide();
			clearTimeout(_cache.timer_show);
			clearTimeout(_cache.timer_hide);
			return true;
		}
		
		clearTimeout(_cache.timer_show);
		_cache['timer_hide']	= setTimeout(function(){
			_hide();
		},100);
	}
	
	/** курсор ушел из попапа */
	t.nextOut	= function() {
		this.hide();
	}
	
	/** курсор из объекта и перешел в popup */
	t.nextOver	= function() {
		clearTimeout(_cache['timer_hide']);
	}
	
	t.html	= htmlHandler(t);
	function htmlHandler(self) {
		var t	= {
			'self'	: self
		};
		
		/** общий каркас tooltip */
		t.main		= function() {
			var txt = '\n\
			<div class="tooltip" style="" onmouseover="TOOLTIP.nextOver();" onmouseout="TOOLTIP.nextOut();">\n\
				<div class="tooltip_arrow" style=""></div>\n\
				<div class="tooltip_body clear_fix">\n\
		\n\
				</div>\n\
			</div>';
			return txt;
		}
		
		/** показываем информацию о вещах */
		t.typeItems	= function() {
			var txt		= '';
			var param	= _cache.param;
			var extra	= typeof param.extra != 'undefined' && typeof param.extra.extra != 'undefined' ? param.extra.extra : {};
			
			/**  
			 * {
			 *	'type'		: 'items',
			 *	'tooltip_id'	: 'item_9',
			 *	'id'		: '9',			// item_id
			 *	'extra'		: {
			 *		'room'	: 'dressingroom',	// popup в одевалке
			 *		'index'	:'0',			// index - вещи в таблице 
			 *		'extra'	:'[]'			// перекрытие каких-либо параметров (например уровень вещи и т.п.)
			 *	}
			 * }
			 **/
			
			
			var info	= tooltips[param.tooltip_id];
			//log(info);
			//log(param.extra.extra);
			
			var replace	= {
				'IMG_URL'	: IMG_URL,
				'MONEY_1'	: g('icon.money_1'),
				'NAME'		: info.name,
				'LEVEL'		: typeof extra.level != 'undefined' ? "(" + extra.level + " ур.)" : '',
				'STAT'		: _getStat(info),
				'UPGRADE_STAT'	: _getUpgradeStat(),
				'MIN_LEVEL'	: _getMinLevel(info),
				'UPGRADES'	: _getUpgrades(info),
				'DESC'		: _getDesc(info),
				'ACTIONS'	: _getActions(info),
				'SWAG'		: ''
			};
			
			if (typeof param.extra !=='undefined' &&  typeof param.extra.room !=='undefined' && param.extra.room == 'dressingroom') {
					/** моя одевалка */
					var item	= PLAYER.items.getInfo(param.extra.index);
					/** котомка действует */
					if (item.group == 6 && PLAYER.swag.getInfo('till')>time()) {
						var rr = '<div class="alink pointer {CLASS}" onclick="{CLICK}"><span>{TITLE}</span></div>';
						replace['SWAG']	= rr.format({
							'CLICK'		: item.bag == 6 ? ' PLAYER.items.doUnSwag('+param.extra.index+')' : ' PLAYER.items.doSwag('+param.extra.index+')',
							'TITLE'		: item.bag == 6 ? '<b></b> В одевалку' : '<b></b> В котомку',
							'CLASS'		: item.bag == 6 ? 'yellow yellow_icon' : 'green green_icon'
						});
					}
			}
			
			txt	= '\n\
				<div class="mt12 mr10 mb12 ml10 mxw280">\n\
					<div class="clear_fix">\n\
						<div class="fl_l bold white mb10 uppercase">{NAME} {LEVEL}</div>\n\
						<div class="fl_r">{SWAG}</div>\n\
					</div>\n\
					{STAT}\n\
					{UPGRADE_STAT}\n\
					{MIN_LEVEL}\n\
					{DESC}\n\
					{UPGRADES}\n\
					{ACTIONS}\n\
					\n\
				</div>\n\
				';
			return txt.format(replace);
			
			/** 
			 * -----------------------------------------------------
			 *			PROTECTED
			 * -----------------------------------------------------
			 **/
			/** возращает улучшения статов которые дает вещь */
			function _getStat(info) {
				var txt	= '';
				if (typeof info.stat !='undefined') {
					txt	+= '<div class="mb10">Характеристики:  ';
					var bb	= ['power','block','dexterity','endurance','charisma'];
					for (var i in bb) {
						var key = bb[i];
						if (intval(info.stat[key])!=0) {
							if (intval(info.stat[key])>0) {
								txt += '<span class="white">+'+info.stat[key]+ g('icon.t_stat_'+key) + '</span>';
							} else {
								txt += '<span class="white">'+info.stat[key]+ g('icon.t_stat_'+key) + '</span>';
							}
						}
					
						if (typeof extra.list_stat != 'undefined' && typeof extra.list_stat[key] != 'undefined') {
							txt += '<span class="green bold">+'+extra.list_stat[key]+ g('icon.t_stat_'+key) + '</span>';
						}
					}
					txt	+= '</div>';
				}
				return txt;
			}

			/** минимальный уровень для покупки */
			function _getMinLevel(info) {
				var txt	= '';
				
				if (typeof info.min_level!='undefined') {
					txt	= '<div class=" ">Требование для покупки: <span class="white">мин. '+info.min_level+'</span> ' + g('icon.t_stat_level') +'</div>';
				}
				
				return txt;
			}
			
			/** описание вещи*/
			function _getDesc(info) {
				var txt	= '';
				
				if (typeof info.desc !='undefined') {
					txt	= '<div class="mb5 lh150">'+info.desc+'</div>';
				}
				
				if (typeof extra.group != undefined && typeof extra.list_ch != undefined && extra.group == 6) {
					txt	= txt.format(extra.list_ch);
				}
				
				return txt;
			}
			
			/** улучшенные статы */
			function _getUpgradeStat() {
				var txt	= '';
				return '';
				if (count(extra.list_stat)==0)
					return txt;
				
				if (typeof extra.list_stat !='undefined') {
					txt	+= '<div class="mb10 yellow">Улучшения:  ';
					var bb	= ['power','block','dexterity','endurance','charisma'];
					for (var i in bb) {
						var key = bb[i];
						if (typeof extra.list_stat[key] != 'undefined') {
							txt += '<span class="green">+'+extra.list_stat[key]+ g('icon.t_stat_'+key) + '</span>';
						}
					}
					txt	+= '</div>';
				}
				return txt;
			}
			
			/** улучшение */
			function _getUpgrades(info) {
				var txt	= '';
				
				/** можно ли улучшать */
				if (typeof extra.can_upgrade != 'undefined' && extra.can_upgrade == 0) {
					return txt;
				}
				
				if (typeof info.upgrades !='undefined') {
					txt	= '<div class="">Можно улучшать в <span style="color:yellow;" class="alink" onclick="ACTIONS.smith.master.screenMain();">кузнице</span> до '+info.upgrades+'</div>';
					
				}
				
				return txt;
			}
			
			/** действия */
			function _getActions(info) {
				var txt	= '';
				
				if (typeof param.extra !=='undefined') {
					/** моя одевалка */
					var item	= PLAYER.items.getInfo(param.extra.index);
					
					/** Для туториала. На втором шаге нужно обработать клик по клавище одеть.*/
					var extra_tutorial	= '';
					var extra_tutorial_click= '';
					
					if ($(_cache.obj).attr('t_step')!= 'undefined' && $(_cache.obj).attr('t_id') != 'undefined') {
						extra_tutorial		= ' t_step="'+$(_cache.obj).attr('t_step')+'" '+' t_id="'+$(_cache.obj).attr('t_id')+'" ';
						extra_tutorial_click	= ' TUTORIAL.click(this); ';
					}
					
					if (typeof param.extra.room !=='undefined' && param.extra.room == 'dressingroom') {
						var replace	= {
							'ACTION'	: item.activated == 1 ? 'PLAYER.items.deActivate('+param.extra.index+');' : 'PLAYER.items.activate('+param.extra.index+');',
							'TITLE'		: item.activated == 1 ? 'Снять' : 'Надеть',
							'DROP'		: 'Выбросить',
							'DROP_CLICK'	: 'GLOBAL.setObj(this, -70); PLAYER.items.drop('+param.extra.index+')',
							'SELL'		: 'Продать',
							'SELL_CLICK'	: 'GLOBAL.setObj(this, -70); PLAYER.items.sell('+param.extra.index+')',
							'T_EXTRA'	: extra_tutorial,
							'T_EXTRA_CLICK'	: extra_tutorial_click
						};
						
						
						
						
						txt	= '<div class="clear_fix mt10">\n\
							<div class="dark_button uppercase fl_l mr3" {T_EXTRA} onclick="{ACTION} {T_EXTRA_CLICK}"><b></b><span>{TITLE}</span></div>\n\
							<div class="dark_button uppercase dark_button_gray fl_r w76" onclick="{SELL_CLICK}"><b></b><span>{SELL}</span></div>\n\
							<div class="dark_button uppercase dark_button_gray fl_l w80 mr3" onclick="{DROP_CLICK}"><b></b><span>{DROP}</span></div>\n\
						</div>'.format(replace);
					}
					
					
				}
				
				
				
				return txt;
			}
			
		}
		
		t.typeHouse	= function() {
			var txt		= '';
			var param	= _cache.param;
			/**  
			 * {
			 *	'type'		: 'items',
			 *	'tooltip_id'	: 'item_9',
			 *	'id'		: '9',			// item_id
			 *	'extra'		: {
			 *		'my'	: true,	// popup в одевалке
			 *		'index'	:'0',			// index - вещи в таблице 
			 *	}
			 * }
			 **/
			
			var info	= tooltips[param.tooltip_id]
			var replace	= {
				'IMG_URL'	: IMG_URL,
				'MONEY_1'	: g('icon.money_1'),
				'NAME'		: info.name,
				'DESC'		: _getDesc(info),
				'ACTIONS'	: _getActions(info)
			};
			
			txt	= '\n\
				<div class="mt12 mr10 mb12 ml10 mxw310">\n\
					<div class="bold white mb10 uppercase">{NAME}</div>\n\
					{ACTIONS}\n\
					{DESC}\n\
					\n\
				</div>\n\
				';
			return txt.format(replace);
			
			
			/** 
			 * -----------------------------------------------------
			 *			PROTECTED
			 * -----------------------------------------------------
			
			/** описание вещи*/
			function _getDesc(info) {
				var txt	= '';
				
				if (typeof info.desc !='undefined') {
					txt	= '<div class="mb5 lh150">'+info.desc+'</div>';
				}
				
				return txt;
			}
			
			/** действия */
			function _getActions(info) {
				var txt	= '';
				if (typeof param.extra !=='undefined' && typeof param.extra.my !=='undefined' && param.extra.my) {
					if (param.tooltip_id == 'safe') {
						/** сейфы */
						var have1	= PLAYER.house.have('safe1');
						var have2	= PLAYER.house.have('safe2');
						var replace	= {
							'TITLE1'		: have1 == false ? '<span class="lightgray">'+g('icon.time')+'<span id="tt_safe1_timer" class="day_on">Не действует</span></span>' : '<span class="lightgray">'+ g('icon.time') + '<span id="tt_safe1_timer" class="day_on"></span><script>timer({"id":"tt_safe1_timer","time":'+PLAYER.house.getInfo('safe1')+'});</script></span>',
							'TITLE2'		: have1 == false ? '<span class="lightgray">'+g('icon.time')+'<span id="tt_safe2_timer" class="day_on">Не действует</span></span>' : '<span class="lightgray">'+ g('icon.time') + '<span id="tt_safe2_timer" class="day_on"></span><script>timer({"id":"tt_safe2_timer","time":'+PLAYER.house.getInfo('safe2')+'});</script></span>',
							'ACTION1'		: "ACTIONS.shop.house.show('safe1')",
							'ACTION2'		: "ACTIONS.shop.house.show('safe2')",
							'BTN_TITLE1'		: have1 == false ? 'Активировать' : 'Продлить',
							'BTN_TITLE2'		: have2 == false ? 'Активировать' : 'Продлить'
						};
						
						txt	= '\n\
							<div class="clear_fix">\n\
								<div class="tooltip_inside_box mb8 mr5 fl_l">\n\
									<span class="inlineb w70">Обычный</span>\n\
									{TITLE1}\n\
								</div>\n\
								<div class="dark_button dark_button_grey uppercase fl_r" onclick="{ACTION1}"><b></b><span>{BTN_TITLE1}</span></div>\n\
							</div>\n\
							<div class="clear_fix">\n\
								<div class="tooltip_inside_box mb8 mr5 fl_l">\n\
									<span class="inlineb w70">Кристальный</span>\n\
									{TITLE2}\n\
								</div>\n\
								<div class="dark_button dark_button_grey uppercase fl_r" onclick="{ACTION2}"><b></b><span>{BTN_TITLE2}</span></div>\n\
							</div>\n\
							'.format(replace);
						
					} else {
						/** тотемы - кроме сейфов */
						var have1	= PLAYER.house.have(param.tooltip_id);
						var replace	= {
							'TITLE1'		: have1 == false ? '<span class="lightgray">'+g('icon.time')+'<span id="tt_'+param.tooltip_id+'_timer" class="day_on">Не действует</span></span>' : '<span class="lightgray">'+ g('icon.time') + '<span id="tt_'+param.tooltip_id+'_timer" class="day_on"></span><script>timer({"id":"tt_'+param.tooltip_id+'_timer","time":'+PLAYER.house.getInfo(param.tooltip_id)+'});</script></span>',
							'ACTION1'		: "ACTIONS.shop.house.show('{ID}')".format({'ID':param.tooltip_id}),
							'BTN_TITLE1'		: have1 == false ? 'Активировать' : 'Продлить'
							
						};
						
						txt	= '\n\
							<div class="clear_fix">\n\
								<div class="tooltip_inside_box mb8 mr5 fl_l">\n\
									<span class="inlineb w70">Действует:</span>\n\
									{TITLE1}\n\
								</div>\n\
								<div class="dark_button dark_button_grey uppercase fl_r" onclick="{ACTION1}"><b></b><span>{BTN_TITLE1}</span></div>\n\
							</div>\n\
							'.format(replace);
					}
					
					
				}
				
				
				
				return txt;
			}
		}
		
		/** маленькие красивые подсказки */
		t.typeHint	= function() {
			var txt		= '';
			var param	= _cache.param;
			/**  
			 * {
			 *	'type'		: 'hint',
			 *	'code'		: 'код подсказки',
			 *	'extra'		: {
			 *	}
			 * }
			 **/
			var replace	= {
				'MESSAGE'	: g('hint.'+param.code)
			};
			
			txt	= '\n\
				<div class="mt12 mr10 mb12 ml10 mxw200 lh150">\n\
					{MESSAGE}\n\
				</div>\n\
				';
			return txt.format(replace);
		}
		
		/** описание медалей  */
		t.typeMedals	= function() {
			var txt		= '';
			var param	= _cache.param;
			/**  
			 * {
			 *	'type'		: 'medals',
			 *	'tooltip_id'	: 'код tooltip-а',
			 * }
			 **/
			
			if (typeof tooltips[param.tooltip_id] == 'undefined')
				return '<div class="p10">ERROR: Type of tooltips['+param.tooltip_id+'] undefined</div>';
			
			var replace	= {
				'DESC'		: tooltips[param.tooltip_id].desc,
				'NAME'		: tooltips[param.tooltip_id].name
			};
			
			txt	= '\n\
				<div class="mt12 mr10 mb12 ml10 mxw280">\n\
					<div class="bold white mb10 uppercase">{NAME}</div>\n\
					<div class="mb5 lh150">{DESC}</div>\n\
				</div>\n\
				';
			return txt.format(replace);
		}
		
		/** описание орденов  */
		t.typeOrdens	= function() {
			var txt		= '';
			var param	= _cache.param;
			
			if (typeof tooltips[param.tooltip_id] == 'undefined')
				return '<div class="p10">ERROR: Type of tooltips['+param.tooltip_id+'] undefined</div>';
			
			/**  
			 * {
			 *	'type'		: 'medals',
			 *	'tooltip_id'	: 'код tooltip-а',
			 * }
			 **/
			var replace	= {
				'DESC'		: tooltips[param.tooltip_id].desc,
				'NAME'		: tooltips[param.tooltip_id].name
			};
			
			txt	= '\n\
				<div class="mt12 mr10 mb12 ml10 mxw280">\n\
					<div class="bold white mb10 uppercase">{NAME}</div>\n\
					<div class="mb5 lh150">{DESC}</div>\n\
				</div>\n\
				';
			return txt.format(replace);
		}
		
		/** тултип в штабе  */
		t.typeSchtab	= function() {
			var txt		= '';
			var param	= _cache.param;
			
			var replace	= {
				'ID'		: param.enemy_id,
				'ACTION1'	: 'ACTIONS.schtab.addRobList(1, '+param.enemy_id+'); TOOLTIP.hide()',
				'ACTION2'	: 'ACTIONS.schtab.addRobList(2, '+param.enemy_id+'); TOOLTIP.hide()',
				'ACTION3'	: 'ACTIONS.schtab.addRobList(3, '+param.enemy_id+'); TOOLTIP.hide()',
				'BTN_TITLE1'	: g('location.schtab_add1'),
				'BTN_TITLE2'	: g('location.schtab_add2'),
				'BTN_TITLE3'	: g('location.schtab_add3')
			};
			
			txt	= '<div class="mt12 mr10 mb12 ml10 clear_fix">\n\
					<div class="dark_button dark_button_gray uppercase dblock w160 mb5" onclick="{ACTION1}"><b></b><span>{BTN_TITLE1}</span></div>\n\
					<div class="dark_button dark_button_gray uppercase dblock w160 mb5" onclick="{ACTION2}"><b></b><span>{BTN_TITLE2}</span></div>\n\
					<div class="dark_button dark_button_gray uppercase dblock w160" onclick="{ACTION3}"><b></b><span>{BTN_TITLE3}</span></div>\n\
				   </div>';
			return txt.format(replace);
		}
		
		return t;
	}
	

	
	/**
	 * ---------------------------------------------------------------------
	 *				PROTECTED 
	 * ---------------------------------------------------------------------
	 */
	
	/** подготавливаем tooltip */
	function _start() {	
		/** 
		 * Здесь один важный момент. 
		 * Если попап уже показан - мы просто заменяем в нем контент и перепозиционируем его 
		 * Если же попап нет - мы показываем его с нуля - со всеми задержками и т.п.
		 * */
		
		if (_cache['is_hide']==true) {
			/** нет popup */
			
			_generatePopup();
			_generateHtml();	// запоняем внутренности
			_pos();			// позиционируем
			
			_cache.timer_show	= setTimeout(function(){
				_show(300);	// показываем		// настраиваем 
				_after();
			},500);
		} else {
			/** есть popup */
			_generatePopup();
			_generateHtml();
			_pos();
			_show(200);	// показываем
			_after();
		}
		
		_cache.obj.onmouseout=function () {
			TOOLTIP.hide();
		}
	}
	
	function _generatePopup() {
		$(t.path.main).remove();
		$('body').append('<div id="'+str_replace('#','',t.path.main)+'" style="display:none;" class="bb"></div>');
		$(t.path.main).html(t.html.main());
	}
	
	/** формируем внутреннюю часть */
	function _generateHtml() {
		var txt	= '';
		switch (_cache.param.type) {
			case 'house':
				txt	= t.html.typeHouse();
				break;
			case 'items':
				txt	= t.html.typeItems();
				break;
			case 'hint':
				txt	= t.html.typeHint();
				break;
			case 'medals':
				txt	= t.html.typeMedals();
				break;
			case 'ordens':
				txt	= t.html.typeOrdens();
				break;
			case 'schtab':
				txt	= t.html.typeSchtab();
				break;
			default:
				txt	= '<span class="p10">Type of Tooltip Undefined. Check Type param</span>';
				break;
		}
		
		$(t.path.content).html(txt);
	}
	
	/** показываем tooltip. Вызывается по timeout */
	function _pos() {
		/** получаем позицию */
		var content_off	= $('#content').offset();
		
		var off		= $(_cache.obj).offset();
		var size_w	= $(_cache.obj).width();
		var size_h	= $(_cache.obj).height();
		
		var tooltip_w	= $(t.path.main).width();
		var tooltip_h	= $(t.path.main).height();
		
		var content_w	= $('#content').width();
		
		var pos_c	= intval(tooltip_w / 2)-10;
		var pos_y	= limit(off.top + size_h +_cache.param.top);
		var pos_arrow	= pos_c - 7 + +_cache.param.arrow_left; /** позиционирование маленькой стрелочки сверху */
		var pos_x	= limit(off.left+_cache.param.left - (pos_c - intval((size_w  / 2))) ,0);
		
		/** корректируем */
		if (pos_x - content_off.left < 0 ) {
			/** выход слева*/
			var bb = (content_off.left - pos_x)+15;
			
			pos_arrow	= pos_arrow - bb; 
			pos_x		= pos_x + bb;
		} else if ( (pos_x + tooltip_w) > (content_off.left + content_w)  ) {
			/** выход справа*/
			var bb = (pos_x + tooltip_w) - (content_off.left + content_w)+15;
			
			pos_arrow	= pos_arrow + bb; 
			pos_x		= pos_x - bb;
		}
		
		$(t.path.arrow).css({'left':pos_arrow+'px'});
		$(t.path.main).css({'left':pos_x+'px','top':pos_y+'px'});
	}
	
	/** анимируем показ */
	function _show(timeout) {
		$(t.path.main).show('drop',{direction:"down",'distance':30},timeout,function(){
			
		});
	}
	
	/** _hide - вызывается по рабатыванию timeout */
	function _hide() {
		if (_cache.is_hide)
			return false;
		
		$(t.path.main).stop().hide('drop',{direction:"down",'distance':30},300,function(){
			// 'percent':10,'size':1,
			$(this).remove();
			$('.ui-effects-wrapper').remove();
			_cache.is_hide	= true;
		});
		
	}
		
	/** привязка на наведение т.п - действия после показа */
	function _after() {
		_cache.is_hide	= false;
	}
	
	return t;
}

/** 
 *-------------------------------------------------------------------   
 *			FAQ
 *-------------------------------------------------------------------   
 **/

function faqHandler(conf, obj) {
	var t	= {};
	
	var _cache	= {
		id	: '',
		title	: 'FAQ',//заголовок по-умолчанию
		list	: [],
		data	: {},	//данные в объекте
		text	: [],	//данные в массиве для вывода в html
		shown_id: 0
	};
	
	/** принимаем данные в conf и передаем в this.html() */
	t.start		= function(conf) {
		if (typeof conf != 'undefined') {
			if (typeof conf.id != 'undefined') {
				_cache.id = '#' + conf.id;
			}
			
			if (typeof conf.title != 'undefined') {
				_cache.title = conf.title;
			} 
			
			if (typeof conf.list != 'undefined') {
				_cache.list = conf.list;
			}
			
			if (typeof conf.shown_id != 'undefined') {
				_cache.shown_id = conf.shown_id;
			}
		}
		
		this.show();
	}
	
	/** показываем */
	t.show	= function() {
		$(_cache.id).html(this.html.mainBlock());
		SKIN.initShown(_cache.shown_id,1);
		autoSize();
	}
	
	/** выводим вопросы и ответы */
	t.html	= htmlHandler(t);
	function htmlHandler(self){
		var t	= {
			'self'	: self
		}
		
		t.makeInnerBlock= function() {
			var txt		= '';
			var temp	= []
			for (var i=0; i< _cache.list.length; i++) {
				var key		= _cache.list[i];

				_cache.data[key] = {};
				_cache.data[key]['question']	= g('faq.data_' + key + 'q');
				_cache.data[key]['answer']	= g('faq.data_' + key + 'a');

				temp.push('<div class="m2"><div class="active_item_block p5 pl3" onclick="FAQ.click(this)"><span class="inlineb w20 iconsp help"></span>' +_cache.data[key]["question"]+'</div><div class="pt5 pb10 pl23 pr15 black hidden">'+_cache.data[key]["answer"]+'</div></div>');
			}
			
			return temp.join('');
		}
		
		/** общий контейнер */
		t.mainBlock	= function() {
		
			var replace	= {
				'TITLE'	: _cache.title,
				'HTML'	: this.makeInnerBlock(),
				'SHOWN_ID': SKIN.nowScreen() == SCREEN_FAQ_SUB ? '' : _cache.shown_id,
				'WIKI'	: SKIN.nowScreen() == SCREEN_FAQ_SUB ? '' : g('icon.wiki'),
				'CLS'	: SKIN.nowScreen() == SCREEN_FAQ_SUB ? '' : 'SKIN.openIfShown(' + _cache.shown_id + '); slide_block pointer',
				'CLICK'	: SKIN.nowScreen() == SCREEN_FAQ_SUB ? '' : 'SKIN.toggleShown(' + _cache.shown_id + ',this)'
				
			};

			var txt = '<div class="static_block mt10" >\n\
				<div class="block_title center bold uppercase {CLS}" onclick="{CLICK}"><div class="title_icon"></div>{TITLE}</div>\n\
				<div class="lh150 clear_fix shown_{SHOWN_ID}">{HTML}</div>\n\
				<div class="wiki pointer" onclick="FAQ.screenMain();">{WIKI}</div>\n\
			</div>'.format(replace);

			return txt;
		}
		
		return t;
	}
	
	/** при клике по вопросу */
	t.click = function(obj){
		$(obj).toggleClass('open');
		$(obj).next().toggleClass('hidden');
		autosize();
	}
	
	/** кликнули по иконке */
	t.screenMain	= function() {		
		SKIN.main(SKIN.parse('faq/faq_main'), SCREEN_FAQ);
	}
	
	/** Внутренние страницы */
	t.screenInner	= function(page) {
		SKIN.main(SKIN.parse('faq/faq_inner', {'page':page}), SCREEN_FAQ_SUB);
	}
	
	return t;
}

/** 
 *-------------------------------------------------------------------   
 *			QUEST
 *-------------------------------------------------------------------   
 **/

function questHandler() {
	var t	= {
		path	: {
			main	: '#quest_stage'	// может изменяться в start()
		}
	};
	
	
	var _QUEST_MAX_STEPS	= 15;
	var _cache		= {
		stage	: null,		// по умолчанию первый квест
		step	: 1		// текущий активный квест
	};
		
	/** пуск */
	t.start		= function(conf) {
		/** id экрана квестов (по умолчанию первый квест, но можно форсировать запуск любого, передав id при запуске) */
		_cache.stage		= conf.stage;
		_cache.step		= conf.step;
		_cache.can_new_stage	= conf.can_new_stage;
		
		if (typeof conf.path_id !='undefined')
			this.path.main	= conf.path_id;
		
		/** */
		_show();
	}
	
	/** запускаем шаблон раздела */
	t.screenMain	= function() {		
		SKIN.main(SKIN.parse('test/test_quest'), SCREEN_QUEST);
	}

	/** */
	t.showInfo	= function(step_id, cls) {
		var ok	= function(r) {
			var p	= popup();
			p.add({
				'message'	: r.txt,
				'title'		: r.name,
				'width'		: 450,
				'cls'		: cls
			});

			/** если можно окончить */
			if (r.status == 0) {
				if (r.can_end == 1) {
					p.set({
						'button_yes'	: {
							'title'	: g('location.quest_try_end'),
							'action': function() {
								QUEST.tryEnd(step_id);
							}
						}
					});
				} else {
					p.set({
						'button_yes_gray'	: {
							'title'	: g('location.quest_try_end'),
							'action': function() {
								QUEST.tryEnd(step_id);
							}
						}
					});
				}
			}

			/** чтобы корректно отрабатывал тутор */
			GLOBAL.set(ON_CLOSE_L_POPUP,function(){
				TUTORIAL.onClosePopup();
			});
			p.show();
		};

		API.call('quest.getQuestInfo',{'step_id':step_id},ok,t.error);
	}

	/** пробуем завершить квест */
	t.tryEnd	= function(step_id) {
		var ok	= function(r) {
			bOk(g('location.quest_end_ok'));
			lPopupRemove();
			ACTIONS.quest.screenMain();
		}

		API.call('quest.tryEnd',{'step_id':step_id},ok,t.error);
	}
	
	/** пытаемся завершить этап квеста - нажали кнопку далее */
	t.tryNewStage	= function() {
		API.call('quest.tryNewStage',{},function(){
			ACTIONS.quest.screenMain();
		},t.error);
	}
	
	/** наши ошибки */
	t.error		= function(r) {
		if (r.code == 4) {
			return underConstruction();
		}
		
		bAlert(g('error.quest_'+r.code));
	}
	
	/** показываем */
	function _show() {
		$(t.path.main).html(_html());
		autoSize();
	}
	
	/** выводим */
	function _html(){
		var conf	= _getConfig(_cache.stage);
		var replace	= {
			'DESC'	: conf.main.desc,
			'IMAGE'	: conf.main.image,
			'BTN'	: _cache.can_new_stage == 1 ? '<div class="button mauto dblock w150" onclick="QUEST.tryNewStage();"><span>Далее</span></div>' : '',
			'HTML'	: _htmlInner()
		};

		var txt = '<div class="quest_stories {IMAGE}">\n\
				   <div class="pt35 ml180 pl15 pr10">{DESC}</div>\n\
			   </div>\n\
			   <div class="quests_bgr">{HTML}</div>\n\
			   {BTN}'.format(replace);

		return txt;
	}
	
	/** выводим */
	function _htmlInner(){
		var conf	= _getConfig(_cache.stage);
		
		var temp	= []
		for (var i=1; i<= _QUEST_MAX_STEPS; i++) {
			
			var key		= conf.path[i];
			if(typeof key.arrow == 'undefined'){
				key.arrow = '';
			}
			
			var replace	= {
				'NUM'	: 'num'+(i),
				'POS'	: 'pos'+key.pos,
				'ARROW'	: 'arrow_'+key.arrow,
				'ICON'	: key.icon,
				'ENDED'	: i < _cache.step ? 'ended' : '',
				'NOW'	: i+1 == _cache.step ? 'now' : '',
				'CLICK'	: i <= _cache.step ? 'GLOBAL.setObj(this);  QUEST.showInfo('+(i)+', \''+key.icon+'\');' : '',
				'TUTORIAL_ID'	: i == 1 ? 'tutorial_quest_1' : '',
				'TUTORIAL_CLICK': i == 1 ? 'TUTORIAL.click(this);' : ''
			};
			
			log(i,_cache.step);
			
			var txt		= '<div class="quest {NUM} {POS} {ARROW} {ICON} {ENDED} {NOW}" onclick="GLOBAL.setObj(this); {TUTORIAL_CLICK} {CLICK}" id="{TUTORIAL_ID}"><div class="quest_type"></div><div class="quest_bgr"></div><div class="quest_arrow"></div></div>'.format(replace);
			temp.push(txt);
		}

		return temp.join('');
	}
	
	/** конфиги */
	function _getConfig(stage) {
		var conf	= {};
		
		conf[JS_SETTINGS_QUEST_STAGE1]	= _quest_stage1();	/** первый экран квестов */
		conf[JS_SETTINGS_QUEST_STAGE2]	= _quest_stage2();	/** второй экран квестов */
		conf[JS_SETTINGS_QUEST_STAGE3]	= _quest_stage3();	/** третий экран квестов */
	
		/**
		 * -------------------------------------------------------------
		 *			ФУНКЦИИ СЦЕНАРИЕВ 
		 * -------------------------------------------------------------
		 **/
		
		/** первый экран квестов */
		function _quest_stage1() {
			var conf	= {
				'main'	: {
					'title'		: g('quest.title1'),
					'desc'		: g('quest.desc1'),
					'image'		: PLAYER.profile.getInfo('race') == 0 ? 'quest_story_1_2' : 'quest_story_1_1'
				},
				'path'	: {
					/** 1. Проведите 5 боев в бодалке. */
					1	: {
						'pos'		: 1,			// позиция (от 1 до 15)
						'icon'		: PLAYER.profile.getInfo('race') == 0 ? 'fight2' : 'fight1',		// иконка (fight, training и т. п.)
						'arrow'		: 'right'		// положение стрелки относительно блока
					},
					/** 2. Поработайте 1 час на ферме. */
					2	: {
						'pos'		: 2,
						'icon'		: 'farm',
						'arrow'		: 'right'
					},
					/** 3. Отправляйтесь в дозор на 10 минут. */
					3	: {
						'pos'		: 3,
						'icon'		: 'watch',
						'arrow'		: 'right'
					},
					/** 4. Получите в бодалке 500 золота. */
					4	: {
						'pos'		: 4,
						'icon'		: PLAYER.profile.getInfo('race') == 0 ? 'fight2' : 'fight1',
						'arrow'		: 'right'
					},
					/** 5. Добудьте 10 кристаллов в шахте. */
					5	: {
						'pos'		: 5,
						'icon'		: 'mine',
						'arrow'		: 'bottom'
					},
					/** 6. Победите 5 противников в бодалке. */
					6	: {
						'pos'		: 10,
						'icon'		: PLAYER.profile.getInfo('race') == 0 ? 'fight2' : 'fight1',
						'arrow'		: 'left'
					},
					/** 7. Активируйте одну специализацию. */
					7	: {
						'pos'		: 9,
						'icon'		: 'rate',
						'arrow'		: 'left'
					},
					/** 8. Улучшить местность до 5-го уровня. */
					8	: {
						'pos'		: 8,
						'icon'		: 'place',
						'arrow'		: 'left'
					},
					/** 9. Отправляйтесь в дозор на 60 минут */
					9	: {
						'pos'		: 7,
						'icon'		: 'watch',
						'arrow'		: 'left'
					},
					/** 10. Дорастите до 5-го уровня. */
					10	: {
						'pos'		: 6,
						'icon'		: 'levelup',
						'arrow'		: 'bottom'
					},
					/** 11. Пните 5 раз монстра на чужой поляне. */
					11	: {
						'pos'		: 11,
						'icon'		: 'monster',
						'arrow'		: 'right'
					},
					/** 12. Улучшить хибару до 5-го уровня. */
					12	: {
						'pos'		: 12,
						'icon'		: 'house',
						'arrow'		: 'right'
					},
					/** 13. промежуточная награда: золото 4000 */
					13	: {
						'pos'		: 13,
						'icon'		: 'gold',
						'arrow'		: 'right'
					},
					/** 14. Увеличьте все характеристики до 20. */
					14	: {
						'pos'		: 14,
						'icon'		: 'training',
						'arrow'		: 'right'
					},
					/** 15. Победите 5 противников выше вас на один уровень. */
					15	: {
						'pos'		: 15,
						'icon'		: 'highlevel',
						'arrow'		: 'right'
					}
				}
			}
			
			return conf;
		}
		
		/** второй экран квестов */
		function _quest_stage2() {
			var conf	= {
				'main'	: {
					'title'		: g('quest.title2'),
					'desc'		: g('quest.desc2'),
					'image'		: 'quest_story_2'
				},
				'path'	: {
					/** 16. Найдите 5 рабов в дозоре. */
					1	: {
						'pos'		: 1,
						'icon'		: 'watch',
						'arrow'		: 'bottom'
					},
					/** 17. Добудьте 20 кристаллов в шахте. */
					2	: {
						'pos'		: 6,
						'icon'		: 'mine',
						'arrow'		: 'right'
					},
					/** 18. Победите подряд 10 противников в бодалке. */
					3	: {
						'pos'		: 7,
						'icon'		: PLAYER.profile.getInfo('race') == 0 ? 'fight2' : 'fight1',
						'arrow'		: 'left_bottom'
					},
					/** 19. Отработайте 10 часов на ферме */
					4	: {
						'pos'		: 11,
						'icon'		: 'farm',
						'arrow'		: 'right'
					},
					/** 20. Улучшите ограду до 5-го уровня. */
					5	: {
						'pos'		: 12,
						'icon'		: 'fence',
						'arrow'		: 'right_top'
					},
					/** 21. Победите в 15 боях с сильным противником */
					6	: {
						'pos'		: 8,
						'icon'		: 'highlevel',
						'arrow'		: 'left_top'
					},
					/** 22. Заблокируйте 3000 урона  */
					7	: {
						'pos'		: 2,
						'icon'		: 'block_damage',
						'arrow'		: 'right'
					},
					/** 23. Сходите 12 раз в дозор, ни разу не уснув. */
					8	: {
						'pos'		: 3,
						'icon'		: 'watch',
						'arrow'		: 'right'
					},
					/** 24. Получите в бодалке 3000 золота. */
					9	: {
						'pos'		: 4,
						'icon'		: PLAYER.profile.getInfo('race') == 0 ? 'fight2' : 'fight1',
						'arrow'		: 'right'
					},
					/** 25. Увеличьте все характеристики на 5. */
					10	: {
						'pos'		: 5,
						'icon'		: 'training',
						'arrow'		: 'bottom'
					},
					/** 25. 26. Прогоните монстра с поляны. */
					11	: {
						'pos'		: 10,
						'icon'		: 'monster',
						'arrow'		: 'left'
					},
					/** 27. Промежуточная награда: 25 кристаллов. */
					12	: {
						'pos'		: 9,
						'icon'		: 'gold',
						'arrow'		: 'left_bottom'
					},
					/** 28. Сходите 18 раз в дозор, ни разу не уснув. */
					13	: {
						'pos'		: 13,
						'icon'		: 'watch',
						'arrow'		: 'right'
					},
					/** 29. Нанесите противнику 1000 урона */
					14	: {
						'pos'		: 14,
						'icon'		: 'cause_damage',
						'arrow'		: 'right'
					},
					/** 30. Добудьте 1 кристалл в бодалке */
					15	: {
						'pos'		: 15,
						'icon'		: 'crystal',
						'arrow'		: 'right'
					}
				}
			}
			
			return conf;
		}
		
		/** третий экран квестов */
		function _quest_stage3() {
			var conf	= {
				'main'	: {
					'title'		: g('quest.title3'),
					'desc'		: g('quest.desc3'),
					'image'		: 'quest_story_3'
				},
				'path'	: {
					/** 31. Приобретите 2 бутылки Красного дьявола */
					1	: {
						'pos'		: 1,
						'icon'		: 'poison',
						'arrow'		: 'right'
					},
					/** 32. Получите деревянную медаль «Золотой дозорный». */
					2	: {
						'pos'		: 2,
						'icon'		: 'rate',
						'arrow'		: 'left_bottom'
					},
					/** 33. Пните 20 раз монстра на чужой поляне. */
					3	: {
						'pos'		: 6,
						'icon'		: 'monster',
						'arrow'		: 'right'
					},
					/** 34. Промежуточная награда: 45 кристаллов */
					4	: {
						'pos'		: 7,
						'icon'		: 'gold',
						'arrow'		: 'left_bottom'
					},
					/** 35. Отработайте на ферме 16 часов */
					5	: {
						'pos'		: 11,
						'icon'		: 'farm',
						'arrow'		: 'right'
					},
					/** 36. Отправляйтесь в дозор на 300 минут */
					6	: {
						'pos'		: 12,
						'icon'		: 'watch',
						'arrow'		: 'right'
					},
					/** 37. Победите подряд 20 противников в бодалке. */
					7	: {
						'pos'		: 13,
						'icon'		: PLAYER.profile.getInfo('race') == 0 ? 'fight2' : 'fight1',
						'arrow'		: 'top'
					},
					/** 38. Добудьте 30 кристаллов в шахте. */
					8	: {
						'pos'		: 8,
						'icon'		: 'mine',
						'arrow'		: 'right'
					},
					/** 39. Получите бронзовую медаль «Победитель». */
					9	: {
						'pos'		: 9,
						'icon'		: 'rate',
						'arrow'		: 'left_top'
					},
					/** 40. Заработайте на ферме 5000 золота. */
					10	: {
						'pos'		: 3,
						'icon'		: 'farm',
						'arrow'		: 'right'
					},
					/** 41. Улучшите ограду до 7-го уровня. */
					11	: {
						'pos'		: 4,
						'icon'		: 'fence',
						'arrow'		: 'right'
					},
					/** 42. Победите в 25 боях с сильным противником. */
					12	: {
						'pos'		: 5,
						'icon'		: 'highlevel',
						'arrow'		: 'bottom'
					},
					/** 43. Дорастите до 13-го уровня. */
					13	: {
						'pos'		: 10,
						'icon'		: 'levelup',
						'arrow'		: 'left_bottom'
					},
					/** 44. Улучшить одну вещь в кузнице до 21 уровня. */
					14	: {
						'pos'		: 14,
						'icon'		: 'smith',
						'arrow'		: 'right'
					},
					/** 45. Получите бронзовую медаль «Силач». */
					15	: {
						'pos'		: 15,
						'icon'		: 'rate'
					}
				}
			}
			
			return conf;
		}
		
		return conf[stage];
	}
		
	return t;
}

/** 
 *-------------------------------------------------------------------   
 *			PANDORA
 *-------------------------------------------------------------------   
 **/

function pandoraHandler(id){
	var t	= {
		'path'	: {
			'main'	: '#pandora',
			'up'	: '.open .up div',
			'down'	: '.open .down div',
			'keys'	: '#pandora_keys'
		}
	}

	var _cache	= {}


	/** начинаем */
	t.start		= function(id, cls){
		//заносим значения
		this.path.main = '#'+id;
		cls != 'undefined' ? this.path.cls = cls : this.path.cls = '';
		for (var i=1; i<=7; i++) {
			_cache[i]	= {};
			_cache[i].id	= i;
			_cache[i].number= mt_rand(0,9); //отображаемая цифра - (!) полагаю, должна приходить с сервера
			_cache[i].need	= mt_rand(0,9); //нужная цифра - (!) полагаю, должна приходить с сервера
			_cache[i].open	= false;	//открыт ли замок, по умолчанию - все закрыты
		}
		
		_cache.keys	= 10;
		
		_show(); //показываем
	}

	/** цифрой больше */
	t.inc		= function(lock_id){
		if(_cache[lock_id].number ==9)
			return false;

		//инкремент
		_cache[lock_id].number++

		//анимация
		var obj	= '#number'+lock_id+' .numbers div:first-child';
		$(obj).parent().append('<div class="number numb1 number'+(intval(_cache[lock_id].number))+'"></div>');
		$(obj).animate({top : -50}, 150, function(){$(obj).next().animate({top : 3}, 200)});

		setTimeout(function(){
			$(obj).remove()
//			_show();
		},350);

	}

	/** цифрой меньше */
	t.dec		= function(lock_id){
		if(_cache[lock_id].number ==0)
			return false;

		//декремент
		_cache[lock_id].number--

		//анимация
		var obj	= '#number'+lock_id+' .numbers div:first-child';
		$(obj).parent().append('<div class="number numb2 number'+(intval(_cache[lock_id].number))+'"></div>');
		$(obj).animate({top : 50}, 150, function(){$(obj).next().animate({top : 3}, 200)});

		setTimeout(function(){
			$(obj).remove()
//			_show();
		},350);
	}

	/** выводит наш html */
	function _show(){
		$(t.path.main).html(_html());	 //показываем блок
		$(t.path.up).last().show();	 //показываем стрелку вверх для последнего открытого замка
		$(t.path.down).last().show();	 //показываем стрелку вниз для последнего открытого замка
		$(t.path.keys).html(_cache.keys);//показываем отмычки
	}
	
	/** использовать отмычку */
	t.change	= function(){
		if (_cache.keys	== 0){
			return false;
		}		
		
		_cache.keys	= (_cache.keys)-1;
		_show();
	}

	/** общий шаблон */
	function _html(){
		var replace = {
			'HTML'	: _htmlInner(),
			'CLS'	: t.path.cls
		}
		var txt = '<div class="pandora {CLS} mb5"><div></div>{HTML}</div>'.format(replace);

		return txt;
	}

	/** шаблон замков */
	function _htmlInner(){	
		var temp	= []

		for (var i=1; i<=7; i++) {

			if(i === 1) {
				_cache[i].open	= true;
			}

			var prev	= i;

			if(i > 1) {
				prev	= i-1;
			}

			if(_cache[prev].number == _cache[i].need && _cache[prev].open == true) {
				_cache[i].open	= true;
			}

			var replace = {
				'ID'		: 'number'+i,
				'UP'		: _cache[i].open ? '<div onclick="PANDORA.inc('+i+')"></div>' : '', //если замок активен - есть стрелка
				'DOWN'		: _cache[i].open ? '<div onclick="PANDORA.dec('+i+')"></div>' : '', //если замок активен - есть стрелка
				'NUMBER'	: _cache[i].open ? _cache[i].number : '*', //если неактивен - прячем цифру
				'CLS'		: _cache[i].open ? 'open' : '' //если открыт - добавляем класс
			}

			var txt = '<div class="{CLS}" id="{ID}">\n\
					<div class="up">{UP}</div>\n\
					<div class="numbers"><div class="number numb0 number{NUMBER}"></div></div>\n\
					<div class="bg_number"></div>\n\
					<div class="down">{DOWN}</div>\n\
				   </div>'.format(replace);

			temp.push(txt);
		}

		return temp.join('');
	}

	return t;
}


/** 
 *-------------------------------------------------------------------   
 *			Отладка
 *-------------------------------------------------------------------   
 **/

function debugHandler() {
	var t	= {
		path	: {
			'template'	: '#debug_js_info div[rel=template]',
			'hs'		: '#debug_js_info div[rel=hs]',
			'mysql'		: '#debug_js_info div[rel=mysql]',
			'm_Cache'	: '#debug_js_info div[rel=m_cache]'
		}
	}
	
	/** лог - через одну функцию. В дальнейшем будет переписан для логирования через html */
	t.log		= function(data) {
		log(data);
	}
	
	t.template	= function(txt) {
		if (txt == 'global/mainContainer')
			return;
		
		txt	= '<div class="row_block">' + txt + '.ejs</div>';
		$(this.path.template).prepend(txt);
	}
	
	/** список запросов к hs */
	t.hs		= function(txt) {
		txt	= '<div class="row_block">' + txt + '</div>';
		$(this.path.hs).prepend(txt);
	}
	
	/** список запросов к mysql */
	t.mysql		= function(txt) {
		txt	= '<div class="row_block">' + txt + '</div>';
		$(this.path.mysql).prepend(txt);
	}
	
	/** список запросов к mCache */
	t.mCache	= function(txt) {
		txt	= '<div class="row_block">' + txt + '</div>';
		$(this.path.m_cache).prepend(txt);
	}
	
	return t;
}
